Commit c7c53f5b authored by Linus Torvalds's avatar Linus Torvalds

Import 2.1.77

parent 3c8de19e
......@@ -572,10 +572,12 @@ S: USA
N: Grant Guenther
E: grant@torque.net
D: drivers for parallel port devices: ppa, ez, bpcd
D: original architect of the parallel-port sharing scheme.
S: 906-1001 Bay St.
S: Toronto, Ontario, M5S 3A6
W: http://www.torque.net/linux-pp.html
D: original author of ppa driver for parallel port ZIP drive
D: original architect of the parallel-port sharing scheme
D: PARIDE subsystem: drivers for parallel port IDE & ATAPI devices
S: 44 St. Joseph St., Suite 506
S: Toronto, Ontario, M4Y 2W4
S: Canada
N: Richard Gnther
......
......@@ -32,8 +32,6 @@ digiepca.txt
- info on Digi Intl. {PC,PCI,EISA}Xx and Xem series cards.
exception.txt
- how linux v2.1 handles exceptions without verify_area etc.
ez.txt
- documentation for the SyQuest parallel port EZ drive support.
filesystems/
- directory with info on the various filesystems that Linux supports.
ftape.txt
......@@ -70,6 +68,8 @@ nfsroot.txt
- short guide on setting up a diskless box with NFS root filesystem
oops-tracing.txt
- how to decode those nasty internal kernel error dump messages.
paride.txt
- information about the parallel port IDE subsystem.
parport.txt
- how to use the parallel-port driver.
ramdisk.txt
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -2,8 +2,6 @@
- this file (info on CD-ROMs and Linux)
aztcd
- info on Aztech/Orchid/Okano/Wearnes/Conrad/CyCDROM driver.
bpcd
- info on MicroSolutions backpack CDROM
cdrom-standard.tex
- LaTeX document on standardizing the CD-ROM programming interface.
......
linux/Documentation/cdrom/bpcd (c) 1996 Grant R. Guenther <grant@torque.net>
This file documents the bpcd driver for the MicroSolutions backpack CDrom,
an external parallel port device.
There are apparently two versions of the backpack protocol. This
driver knows about the version 2 protocol - as is used in the 4x
and 6x products. There is no support for the sound hardware that
is included in some models. It should not be difficult to add
support for the ATAPI audio play functions and the corresponding
ioctls.
The driver was developed by reverse engineering the protocol
and testing it on the backpack model 164550. This model
is actually a stock ATAPI drive packaged with a custom
ASIC that implements the IDE over parallel protocol.
I tested with a backpack that happened to contain a Goldstar
drive, but I've seen reports of Sony and Mitsumi drives as well.
Before attempting to use the driver, you will need to
create a new device special file. The following commands will
do that for you:
mknod /dev/bpcd b 41 0
chown root:disk /dev/bpcd
chmod 660 /dev/bpcd
Afterward, you can mount a disk in the usual way:
mount -t iso9660 /dev/bpcd /cdrom
(assuming you have made a directory /cdrom to use as a mount point).
The driver will attempt to detect which parallel port your
backpack is connected to. If this fails for any reason, you
can override it by specifying a port on the LILO command line
(for built in drivers) or the insmod command (for drivers built
as modules). If your drive is on the port at 0x3bc, you would
use one of these commands:
LILO: bpcd=0x3bc
insmod: insmod bpcd bp_base=0x3bc
The driver can detect if the parallel port supports 8-bit
transfers. If so, it will use them. You can force it to use
4-bit (nybble) mode by setting the variable bp_nybble to 1 on
an insmod command, or using the following LILO parameters:
bpcd=0x3bc,1
(you must specify the correct port address if you use this method.)
There is currently no support for EPP or ECP modes. Also,
as far as I can tell, the MicroSolutions protocol does not
support interrupts in the 4-bit and 8-bit modes.
MicroSolutions' protocol allows for several drives to be
chained together off the same parallel port. Currently, this
driver will recognise only one of them. If you do have more
than one drive, it will choose the one with the lowest id number,
where the id number is the last two digits of the product's
serial number.
It is not currently possible to connect a printer to the chained
port on the BackPack and expect Linux to use both devices at once.
If you need to use this driver together with a printer on the
same port, build both the bpcd and lp drivers as modules.
Keep an eye on http://www.torque.net/bpcd.html for news and
other information about the driver. If you have any problems
with this driver, please send me, grant@torque.net, some mail
directly before posting into the newsgroups or mailing lists.
\documentclass{article}
\def\version{$Id: cdrom-standard.tex,v 1.8 1997/11/19 21:58:33 david Exp $}
\def\version{$Id: cdrom-standard.tex,v 1.9 1997/12/28 15:42:49 david Exp $}
\newcommand{\newsection}[1]{\newpage\section{#1}}
\evensidemargin=0pt
......@@ -388,46 +388,6 @@ CDS_DISC_OK& a disc is loaded and everything is fine\cr
}
$$
\subsection{$Disc_status$}
\label{disc status}
As a complement to $drive_status()$, this function can provide {\emph
{some}} information about the current disc that is inserted in the
drive. This function is now implemented internally in the \UCD, so the
low-level drivers do not need to implement this functionality anymore.
The history of development of the CD's use as a carrier medium for
various digital information has lead to many different disc types. This
$ioctl$ makes the false assumption that CDs have {\emph {only one}} type
of data on them. While this is often the case, it is also very common
for CDs to have some tracks with data, and some tracks with audio.
Because this is an existing interface, rather than fixing this interface
by changing the assumptions it was made under, thereby breaking all user
applications that use this function, the \UCD\ implements this $ioctl$
as follows: If the CD in question has audio tracks on it, and it has
absolutly no CD-I, XA, or data tracks on it, it will be reported as
$CDS_AUDIO$. Failing that, if the CD in question has any CD-I tracks
on it, it will be reported as $CDS_XA_2_2$. Failing that, if the CD in
question has any XA tracks on it, it will be reported as $CDS_XA_2_1$.
Finally, if the CD in question has any data tracks on it, it will be
reported as a data CD ($CDS_DATA_1$).
This function can return:
$$
\halign{$#$\ \hfil&$/*$ \rm# $*/$\hfil\cr
CDS_NO_INFO& no information available\cr
CDS_NO_DISC& no disc is inserted, or tray is opened\cr
CDS_AUDIO& Audio disc (2352 audio bytes/frame)\cr
CDS_DATA_1& data disc, mode 1 (2048 user bytes/frame)\cr
CDS_DATA_2& data disc, mode 2 (2336 user bytes/frame)\cr
CDS_XA_2_1& mixed data (XA), mode 2, form 1 (2048 user bytes)\cr
CDS_XA_2_2& mixed data (XA), mode 2, form 1 (2324 user bytes)\cr
}
$$
As far as I know, data \cdrom s are always of type $CDS_DATA_1$. For
some information concerning frame layout of the various disc types, see
a recent version of \cdromh.
\subsection{$Int\ media_changed(struct\ cdrom_device_info * cdi, int\ disc_nr)$}
This function is very similar to the original function in $struct\
......@@ -940,8 +900,46 @@ the current flags.
given. The special value $CDSL_CURRENT$ requests that information
about the currently selected slot is returned.
\item[CDROM_DISC_STATUS] Returns the type of the disc currently in the
drive by a call to $disc_status()$. Return values are as defined in
section~\ref{disc status}.
drive. It should be viewed as a complement to $CDROM_DRIVE_STATUS$.
This $ioctl$ can provide \emph {some} information about the current
disc that is inserted in the drive. This functionality used to be
implemented in the low level drivers, but is now carried out
entirely in \UCD.
The history of development of the CD's use as a carrier medium for
various digital information has lead to many different disc types.
This $ioctl$ is useful only in the case that CDs have \emph {only
one} type of data on them. While this is often the case, it is
also very common for CDs to have some tracks with data, and some
tracks with audio. Because this is an existing interface, rather
than fixing this interface by changing the assumptions it was made
under, thereby breaking all user applications that use this
function, the \UCD\ implements this $ioctl$ as follows: If the CD in
question has audio tracks on it, and it has absolutly no CD-I, XA,
or data tracks on it, it will be reported as $CDS_AUDIO$. If it has
both audio and data tracks, it will return $CDS_MIXED$. If there
are no audio tracks on the disc, and if the CD in question has any
CD-I tracks on it, it will be reported as $CDS_XA_2_2$. Failing
that, if the CD in question has any XA tracks on it, it will be
reported as $CDS_XA_2_1$. Finally, if the CD in question has any
data tracks on it, it will be reported as a data CD ($CDS_DATA_1$).
This $ioctl$ can return:
$$
\halign{$#$\ \hfil&$/*$ \rm# $*/$\hfil\cr
CDS_NO_INFO& no information available\cr
CDS_NO_DISC& no disc is inserted, or tray is opened\cr
CDS_AUDIO& Audio disc (2352 audio bytes/frame)\cr
CDS_DATA_1& data disc, mode 1 (2048 user bytes/frame)\cr
CDS_DATA_2& data disc, mode 2 (2336 user bytes/frame)\cr
CDS_XA_2_1& mixed data (XA), mode 2, form 1 (2048 user bytes)\cr
CDS_XA_2_2& mixed data (XA), mode 2, form 1 (2324 user bytes)\cr
CDS_MIXED& mixed audio/data disc\cr
}
$$
For some information concerning frame layout of the various disc
types, see a recent version of \cdromh.
\item[CDROM_CHANGER_NSLOTS] Returns the number of slots in a
juke-box.
\end{description}
......@@ -1021,4 +1019,3 @@ the first place.
$ \version\ $
\eject
\end{document}
linux/Documentation/ez.txt (c) 1996 Grant R. Guenther <grant@torque.net>
This file documents the ez driver for the parallel port versions of
SyQuest's EZ135 and EZ230 removable media disk drives.
Special thanks go to Pedro Soria-Rodriguez for his help testing
the EZFlyer 230 support.
The drive is actually SyQuest's IDE product with a ShuttleTech
IDE <-> parallel converter chip built in.
Before attempting to access the new driver, you will need to
create some device special files. The following commands will
do that for you:
mknod /dev/eza b 40 0
mknod /dev/eza1 b 40 1
mknod /dev/eza2 b 40 2
mknod /dev/eza3 b 40 3
mknod /dev/eza4 b 40 4
chown root:disk /dev/ez*
chmod 660 /dev/ez*
You can make devices for more partitions (up to 15) if you need to.
You can alter certain driver parameters on the LILO or LOADLIN
command line. The general syntax is
ez=base[,irq]
where base is the base address of the parallel port you want to use
and irq is the interrupt number for that port. By default, the
driver uses the ports at 0x378 and irq 7. You can disable the
interrupt by specifying it as 0. For example, to run the driver
on port 0x3bc without an interrupt, you would append the following
to the LILO command line:
ez=0x3bc,0
If you have configured the driver as a loadable module, you can
adjust these parameters on the insmod command line using the
variables ez_base and ez_irq. For example:
insmod ez ez_base=0x3bc
The driver can detect if the parallel port supports 8-bit
transfers. If so, it will use them.
The driver can be used with or without interrupts. If an IRQ
is specified the driver will use it - if it can. If the irq
number is set to 0, an alternative, polling-based, strategy
will be used. Polling consumes more CPU time, but may be more
stable on some systems.
If you experience timeout errors while using this driver - and
you have enabled interrupts - try disabling the interrupt. I
have heard reports of some parallel ports having exceptionally
unreliable interrupts. This could happen on misconfigured
systems in which an inactive sound card shares the same IRQ with
the parallel port. (Remember that most people do not use the
parallel port interrupt for printing.)
It would be advantageous to use multiple mode transfers,
but ShuttleTech's driver does not appear to use them, so I'm not
sure that the converter can handle it.
It is not currently possible to connect a printer to the chained
port on an EZ drive and expect Linux to use both devices at once.
If you need to do this, build both the ez and lp drivers as modules
and load one or the other as required.
When the EZ230 powers on, the "standby timer" is set to about 6
minutes: if the drive is idle for that length of time, it will
put itself into a low power standby mode. It takes a couple of
seconds for the drive to come out of standby mode. So, if you
load this driver while it is in standby mode, you will notice
a "freeze" of a second or two as the driver waits for the EZ230
to come back to life. Once loaded, this driver disables the
standby timer (until you next power up the EZ230 ...)
Keep an eye on http://www.torque.net/ez135.html for news and
other information about the driver. If you have any problems
with this driver, please send me, grant@torque.net, some mail
directly before posting into the newsgroups or mailing lists.
......@@ -60,7 +60,6 @@ Here is a sample of the available modules included in the kernel sources:
aztcd: Aztech,Orchid,Okano,Wearnes
cm206: Philips/LMS CM206
gscd: Goldstar GCDR-420
bpcd: MicroSolutions backpack CDrom
mcd, mcdx: Mitsumi LU005, FX001
optcd: Optics Storage Dolphin 8000AT
sjcd: Sanyo CDR-H94A
......
......@@ -4,14 +4,14 @@ Written by: Jay Schulist <Jay.Schulist@spacs.k12.wi.us>
Introduction
============
Linux Socket Filtering is a deviation of the Berkely
Linux Socket Filtering is derived from the Berkeley
Packet Filter. There are some distinct differences between
the BSD and Linux Kernel Filtering.
Linux Socket Filtering (LSF) allows a user-space program to
attach a filter onto any socket and allow or disallow certain
types of data to come through the socket. LSF follows exactly
the same filter code structure as the BSD Berkely Packet Filter
the same filter code structure as the BSD Berkeley Packet Filter
(BPF), so refering to the BSD bpf.4 manpage is very helpful in
creating filters.
......@@ -39,4 +39,4 @@ setsockopt(sockfd, SOL_SOCKET, SO_ATTACH_FILTER, &Filter, sizeof(Filter));
setsockopt(sockfd, SOL_SOCKET, SO_DETACH_FILTER, &value, sizeof(value));
See the BSD bpf.4 manpage and the BSD Packet Filter paper written by
Steven McCanne and Van Jacobson of Lawrence Berkely Laboratory.
Steven McCanne and Van Jacobson of Lawrence Berkeley Laboratory.
This diff is collapsed.
......@@ -511,6 +511,13 @@ W: http://www.cyberelk.demon.co.uk/parport.html
W: http://www.cage.curtin.edu.au/~campbell/parbus/
S: Maintained
PARIDE DRIVERS FOR PARALLEL PORT IDE DEVICES
P: Grant Guenther
M: grant@torque.net
L: linux-parport@torque.net
W: http://www.torque.net/linux-pp.html
S: Maintained
PNP SUPPORT
P: Tom Lees
M: tom@lpsg.demon.co.uk
......
VERSION = 2
PATCHLEVEL = 1
SUBLEVEL = 76
SUBLEVEL = 77
ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/)
......@@ -157,6 +157,10 @@ ifdef CONFIG_PNP
DRIVERS := $(DRIVERS) drivers/pnp/pnp.a
endif
ifeq ($(CONFIG_PARIDE),y)
DRIVERS := $(DRIVERS) drivers/block/paride/paride.a
endif
ifdef CONFIG_HAMRADIO
DRIVERS := $(DRIVERS) drivers/net/hamradio/hamradio.a
endif
......@@ -346,10 +350,10 @@ clean: archclean
mrproper: clean
rm -f include/linux/autoconf.h include/linux/version.h
rm -f drivers/net/soundmodem/sm_tbl_{afsk1200,afsk2666,fsk9600}.h
rm -f drivers/net/soundmodem/sm_tbl_{hapn4800,psk4800}.h
rm -f drivers/net/soundmodem/sm_tbl_{afsk2400_7,afsk2400_8}.h
rm -f drivers/net/soundmodem/gentbl
rm -f drivers/net/hamradio/soundmodem/sm_tbl_{afsk1200,afsk2666,fsk9600}.h
rm -f drivers/net/hamradio/soundmodem/sm_tbl_{hapn4800,psk4800}.h
rm -f drivers/net/hamradio/soundmodem/sm_tbl_{afsk2400_7,afsk2400_8}.h
rm -f drivers/net/hamradio/soundmodem/gentbl
rm -f drivers/char/hfmodem/gentbl drivers/char/hfmodem/tables.h
rm -f drivers/sound/*_boot.h drivers/sound/.*.boot
rm -f .version .config* config.in config.old
......
......@@ -966,7 +966,7 @@ static inline long get_it32(struct itimerval *o, struct itimerval32 *i)
static inline long put_it32(struct itimerval32 *o, struct itimerval *i)
{
return (!access_ok(VERIFY_WRITE, i, sizeof(*i)) ||
return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) ||
(__put_user(i->it_interval.tv_sec, &o->it_interval.tv_sec) |
__put_user(i->it_interval.tv_usec, &o->it_interval.tv_usec) |
__put_user(i->it_value.tv_sec, &o->it_value.tv_sec) |
......@@ -1241,7 +1241,7 @@ asmlinkage int osf_wait4(pid_t pid, int *ustatus, int options,
* seems to be a timeval pointer, and I suspect the second
* one is the time remaining.. Ho humm.. No documentation.
*/
asmlinkage int osf_usleep_thread(struct timeval *sleep, struct timeval *remain)
asmlinkage int osf_usleep_thread(struct timeval32 *sleep, struct timeval32 *remain)
{
struct timeval tmp;
unsigned long ticks;
......
......@@ -274,6 +274,8 @@ loader_ok:
oldstylemem:
pop ebx
#else
mov dword ptr [0x1e0], #0
#endif
mov ah,#0x88
int 0x15
......
......@@ -73,7 +73,8 @@ CONFIG_BLK_DEV_IDEDMA=y
# CONFIG_BLK_DEV_MD is not set
# CONFIG_BLK_DEV_RAM is not set
# CONFIG_BLK_DEV_XD is not set
# CONFIG_BLK_DEV_EZ is not set
CONFIG_PARIDE_PARPORT=y
# CONFIG_PARIDE is not set
# CONFIG_BLK_DEV_HD is not set
#
......@@ -240,10 +241,6 @@ CONFIG_LOCKD=y
CONFIG_AUTOFS_FS=y
# CONFIG_UFS_FS is not set
# CONFIG_MAC_PARTITION is not set
#
# Native Language Support
#
# CONFIG_NLS is not set
#
......@@ -269,6 +266,7 @@ CONFIG_82C710_MOUSE=y
# CONFIG_RTC is not set
# CONFIG_VIDEO_DEV is not set
# CONFIG_VIDEO_BT848 is not set
# CONFIG_VIDEO_BWQCAM is not set
# CONFIG_VIDEO_PMS is not set
# CONFIG_NVRAM is not set
# CONFIG_JOYSTICK is not set
......
......@@ -611,7 +611,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
child->tss.i387.hard.twd = 0xffffffff;
}
#ifdef CONFIG_MATH_EMULATION
if ( hard_math ) {
if ( boot_cpu_data.hard_math ) {
#endif
if (last_task_used_math == child) {
clts();
......@@ -639,7 +639,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
}
child->used_math = 1;
#ifdef CONFIG_MATH_EMULATION
if ( hard_math ) {
if ( boot_cpu_data.hard_math ) {
#endif
if (last_task_used_math == child) {
/* Discard the state of the FPU */
......
......@@ -416,7 +416,7 @@ static void setup_frame(int sig, struct k_sigaction *ka,
{
unsigned long seg = __USER_DS;
__asm__("mov %w0,%%fs ; mov %w0,%%gs": "=r"(seg) : "0"(seg));
set_fs(MAKE_MM_SEG(seg));
set_fs(USER_DS);
regs->xds = seg;
regs->xes = seg;
regs->xss = seg;
......@@ -488,7 +488,7 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
{
unsigned long seg = __USER_DS;
__asm__("mov %w0,%%fs ; mov %w0,%%gs": "=r"(seg) : "0"(seg));
set_fs(MAKE_MM_SEG(seg));
set_fs(USER_DS);
regs->xds = seg;
regs->xes = seg;
regs->xss = seg;
......
......@@ -25,6 +25,7 @@
* Alan Cox : Dumb bug: 'B' step PPro's are fine
* Ingo Molnar : Added APIC timers, based on code
* from Jose Renau
* Alan Cox : Added EBDA scanning
*/
#include <linux/kernel.h>
......@@ -924,7 +925,7 @@ __initfunc(void smp_boot_cpus(void))
if (!max_cpus)
{
smp_found_config = 0;
printk("SMP mode deactivated, forcing use of dummy APIC emulation.\n");
printk(KERN_INFO "SMP mode deactivated, forcing use of dummy APIC emulation.\n");
}
/*
......@@ -1063,7 +1064,7 @@ __initfunc(void smp_boot_cpus(void))
if(cpu_present_map&(1<<i))
bogosum+=cpu_data[i].loops_per_sec;
}
printk("Total of %d processors activated (%lu.%02lu BogoMIPS).\n",
printk(KERN_INFO "Total of %d processors activated (%lu.%02lu BogoMIPS).\n",
cpucount+1,
(bogosum+2500)/500000,
((bogosum+2500)/5000)%100);
......
......@@ -178,14 +178,21 @@ __initfunc(unsigned long paging_init(unsigned long start_mem, unsigned long end_
* the error...
*/
if (!smp_scan_config(639*0x400,0x400)) /* Scan the top 1K of base RAM */
smp_scan_config(0xF0000,0x10000); /* Scan the 64K of bios */
}
{
if(!smp_scan_config(0xF0000,0x10000)) /* Scan the 64K of bios */
{
/*
* If it is an SMP machine we should know now, unless the configuration
* is in an EISA/MCA bus machine with an extended bios data area. I don't
* have such a machine so someone else can fill in the check of the EBDA
* here.
* is in an EISA/MCA bus machine with an extended bios data area.
*/
address = *(unsigned short *)phys_to_virt(0x40E); /* EBDA */
address<<=4; /* Real mode segments to physical */
smp_scan_config(address, 0x1000); /* Scan the EBDA */
}
}
}
/* smp_alloc_memory(8192); */
#endif
start_mem = PAGE_ALIGN(start_mem);
......
......@@ -27,12 +27,14 @@ else
if [ "$CONFIG_BLK_DEV_IDEPCI" = "y" ]; then
bool ' Generic PCI bus-master DMA support' CONFIG_BLK_DEV_IDEDMA
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
bool ' Tekram TRM290 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_TRM290
bool ' OPTi 82C621 chipset enhanced support (EXPERIMENTAL)' CONFIG_BLK_DEV_OPTI621
if [ "$CONFIG_BLK_DEV_IDEDMA" = "y" ]; then
bool ' Tekram TRM290 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_TRM290
bool ' NS87415 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_NS87415
fi
fi
fi
fi
bool ' Other IDE chipset support' CONFIG_IDE_CHIPSETS
if [ "$CONFIG_IDE_CHIPSETS" = "y" ]; then
comment 'Note: most of these also require special kernel boot parameters'
......@@ -68,7 +70,16 @@ if [ "$CONFIG_BLK_DEV_RAM" = "y" ]; then
bool ' Initial RAM disk (initrd) support' CONFIG_BLK_DEV_INITRD
fi
tristate 'XT harddisk support' CONFIG_BLK_DEV_XD
tristate 'SyQuest EZ parallel port disk support' CONFIG_BLK_DEV_EZ
if [ "$CONFIG_PARPORT" = "y" -o "$CONFIG_PARPORT" = "n" ] ; then
define_bool CONFIG_PARIDE_PARPORT y
else
define_bool CONFIG_PARIDE_PARPORT m
fi
dep_tristate 'Parallel port IDE device support' CONFIG_PARIDE $CONFIG_PARIDE_PARPORT
if [ "$CONFIG_PARIDE" != "n" ]; then
source drivers/block/paride/Config.in
fi
if [ "$CONFIG_BLK_DEV_HD_IDE" = "y" -o "$CONFIG_BLK_DEV_HD_ONLY" = "y" ]; then
define_bool CONFIG_BLK_DEV_HD y
......
......@@ -14,6 +14,10 @@
# In the future, some of these should be built conditionally.
#
SUB_DIRS :=
MOD_SUB_DIRS := $(SUB_DIRS)
ALL_SUB_DIRS := $(SUB_DIRS) paride
L_TARGET := block.a
L_OBJS := ll_rw_blk.o genhd.o
......@@ -191,14 +195,6 @@ else
endif
endif
ifeq ($(CONFIG_BLK_DEV_EZ),y)
L_OBJS += ez.o
else
ifeq ($(CONFIG_BLK_DEV_EZ),m)
M_OBJS += ez.o
endif
endif
ifeq ($(CONFIG_BLK_DEV_MD),y)
LX_OBJS += md.o
......@@ -244,4 +240,13 @@ else
endif
endif
ifeq ($(CONFIG_PARIDE),y)
SUB_DIRS += paride
MOD_SUB_DIRS += paride
else
ifeq ($(CONFIG_PARIDE),m)
MOD_SUB_DIRS += paride
endif
endif
include $(TOPDIR)/Rules.make
This diff is collapsed.
......@@ -2,7 +2,7 @@
* Code extracted from
* linux/kernel/hd.c
*
* Copyright (C) 1991, 1992 Linus Torvalds
* Copyright (C) 1991-1998 Linus Torvalds
*
*
* Thanks to Branko Lankester, lankeste@fwi.uva.nl, who found a bug
......@@ -105,6 +105,7 @@ static void add_partition (struct gendisk *hd, int minor, int start, int size)
static inline int is_extended_partition(struct partition *p)
{
return (SYS_IND(p) == DOS_EXTENDED_PARTITION ||
SYS_IND(p) == WIN98_EXTENDED_PARTITION ||
SYS_IND(p) == LINUX_EXTENDED_PARTITION);
}
......
/*
* linux/drivers/block/ide-dma.c Version 4.07 December 5, 1997
* linux/drivers/block/ide-dma.c Version 4.08 December 31, 1997
*
* Copyright (c) 1995-1998 Mark Lord
* May be copied or modified under the terms of the GNU General Public License
......@@ -171,8 +171,8 @@ int ide_build_dmatable (ide_drive_t *drive)
}
/*
* Fill in the dma table, without crossing any 64kB boundaries.
* The hardware requires 16-bit alignment of all blocks
* (trm290 requires 32-bit alignment).
* Most hardware requires 16-bit alignment of all blocks,
* but the trm290 requires 32-bit alignment.
*/
if ((addr & 3)) {
printk("%s: misaligned DMA buffer\n", drive->name);
......@@ -247,7 +247,7 @@ static int config_drive_for_dma (ide_drive_t *drive)
int ide_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
{
ide_hwif_t *hwif = HWIF(drive);
unsigned int dma_base = hwif->dma_base;
unsigned long dma_base = hwif->dma_base;
unsigned int count, reading = 0;
switch (func) {
......@@ -288,12 +288,12 @@ int ide_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
}
}
void ide_setup_dma (ide_hwif_t *hwif, unsigned int dma_base, unsigned int num_ports) /* __init */
void ide_setup_dma (ide_hwif_t *hwif, unsigned long dma_base, unsigned int num_ports) /* __init */
{
static unsigned long dmatable = 0;
static unsigned leftover = 0;
printk(" %s: BM-DMA at 0x%04x-0x%04x", hwif->name, dma_base, dma_base + num_ports - 1);
printk(" %s: BM-DMA at 0x%04lx-0x%04lx", hwif->name, dma_base, dma_base + num_ports - 1);
if (check_region(dma_base, num_ports)) {
printk(" -- ERROR, PORT ADDRESSES ALREADY IN USE\n");
return;
......@@ -356,25 +356,26 @@ __initfunc(static long read_pcicfg_dword (byte fn, unsigned short reg))
/*
* Fetch the DMA Bus-Master-I/O-Base-Address (BMIBA) from PCI space:
*/
unsigned int ide_get_or_set_dma_base (ide_hwif_t *hwif, int extra, const char *name) /* __init */
unsigned long ide_get_or_set_dma_base (ide_hwif_t *hwif, int extra, const char *name) /* __init */
{
unsigned int new, dma_base = 0;
unsigned long new, dma_base = 0;
byte bus = hwif->pci_bus, fn = hwif->pci_fn;
if (hwif->mate && hwif->mate->dma_base) {
dma_base = hwif->mate->dma_base - (hwif->channel ? 0 : 8);
} else if (pcibios_read_config_dword(bus, fn, 0x20, &dma_base)) {
} else if (pcibios_read_config_dword(bus, fn, 0x20, (unsigned int *)&dma_base)) {
printk("%s: failed to read dma_base\n", name);
dma_base = 0;
} else if ((dma_base &= ~0xf) == 0 || dma_base == ~0xf) {
printk("%s: dma_base is invalid (0x%04x, BIOS problem)\n", name, dma_base);
printk("%s: dma_base is invalid (0x%04lx, BIOS problem)\n", name, dma_base);
new = ide_find_free_region(16 + extra);
hwif->no_autodma = 1; /* default DMA off if we had to configure it here */
if (new) {
printk("%s: setting dma_base to 0x%04x\n", name, new);
printk("%s: setting dma_base to 0x%04lx\n", name, new);
new |= 1;
(void) pcibios_write_config_dword(bus, fn, 0x20, new);
(void) pcibios_read_config_dword(bus, fn, 0x20, &dma_base);
dma_base = 0;
(void) pcibios_read_config_dword(bus, fn, 0x20, (unsigned int *)&dma_base);
if (dma_base != new) {
if (bus == 0) {
printk("%s: operation failed, bypassing BIOS to try again\n", name);
......
/*
* linux/drivers/block/ide-pci.c Version 1.00 December 8, 1997
* linux/drivers/block/ide-pci.c Version 1.02 December 29, 1997
*
* Copyright (c) 1995-1998 Mark Lord
* May be copied or modified under the terms of the GNU General Public License
*/
/*
* This modules provides support for automatic detection and
* This module provides support for automatic detection and
* configuration of all PCI IDE interfaces present in a system.
*/
......@@ -41,6 +41,7 @@
#define DEVID_NS87410 ((ide_pci_devid_t){PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87410})
#define DEVID_NS87415 ((ide_pci_devid_t){PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87415})
#define DEVID_HT6565 ((ide_pci_devid_t){PCI_VENDOR_ID_HOLTEK, PCI_DEVICE_ID_HOLTEK_6565})
#define DEVID_AEC6210 ((ide_pci_devid_t){0x1191, 0x0005})
#define IDE_IGNORE ((void *)-1)
......@@ -102,6 +103,7 @@ static ide_pci_device_t ide_pci_chipsets[] __initdata = {
{DEVID_OPTI621X,"OPTI621X", INIT_OPTI621, {{0x45,0x80,0x00}, {0x40,0x08,0x00}} },
{DEVID_TRM290, "TRM290", INIT_TRM290, {{0x00,0x00,0x00}, {0x00,0x00,0x00}} },
{DEVID_NS87415, "NS87415", INIT_NS87415, {{0x00,0x00,0x00}, {0x00,0x00,0x00}} },
{DEVID_AEC6210, "AEC6210", NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}} },
{IDE_PCI_DEVID_NULL, "PCI_IDE", NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}} }};
/*
......@@ -111,7 +113,7 @@ static ide_pci_device_t ide_pci_chipsets[] __initdata = {
* by the BIOS, to avoid conflicts later in the init cycle,
* but we don't. FIXME
*/
unsigned int ide_find_free_region (unsigned short size) /* __init */
unsigned long ide_find_free_region (unsigned short size) /* __init */
{
static unsigned short base = 0x5800; /* it works for me */
unsigned short i;
......@@ -228,10 +230,11 @@ __initfunc(static int ide_setup_pci_baseregs (byte bus, byte fn, const char *nam
__initfunc(static void ide_setup_pci_device (byte bus, byte fn, unsigned int ccode, ide_pci_device_t *d))
{
unsigned int port, at_least_one_hwif_enabled = 0, no_autodma = 0;
unsigned short pcicmd = 0;
unsigned short pcicmd = 0, tried_config = 0;
byte tmp = 0, progif = 0, pciirq = 0;
ide_hwif_t *hwif, *mate = NULL;
check_if_enabled:
if (pcibios_read_config_word(bus, fn, 0x04, &pcicmd)
|| pcibios_read_config_byte(bus, fn, 0x09, &progif)
|| pcibios_read_config_byte(bus, fn, 0x3c, &pciirq))
......@@ -247,21 +250,32 @@ __initfunc(static void ide_setup_pci_device (byte bus, byte fn, unsigned int cco
* Maybe the user deliberately *disabled* the device,
* but we'll eventually ignore it again if no drives respond.
*/
if (ide_setup_pci_baseregs(bus, fn, d->name)
|| pcibios_write_config_word(bus, fn, 0x04, pcicmd|1)
|| pcibios_read_config_word(bus, fn, 0x04, &pcicmd)
|| !(pcicmd & 1))
if (tried_config++
|| ide_setup_pci_baseregs(bus, fn, d->name)
|| pcibios_write_config_word(bus, fn, 0x04, pcicmd|1))
{
printk("%s: device disabled (BIOS)\n", d->name);
return;
}
no_autodma = 1; /* default DMA off if we had to configure it here */
printk("%s: device enabled (Linux)\n", d->name);
goto check_if_enabled;
}
if (!pciirq || pciirq >= NR_IRQS) { /* is pciirq invalid? */
if (pciirq || (progif & 0x5)) /* don't complain if using "legacy" mode */
printk("%s: BIOS returned %d for IRQ (ignored)\n", d->name, pciirq);
pciirq = 0; /* probe for it instead */
if (tried_config)
printk("%s: device enabled (Linux)\n", d->name);
/*
* Can we trust the reported IRQ?
*/
if ((ccode >> 16) != PCI_CLASS_STORAGE_IDE || (progif & 5) != 5) {
printk("%s: not 100%% native mode: will probe irqs later\n", d->name);
pciirq = 0;
} else if (tried_config) {
printk("%s: will probe irqs later\n", d->name);
pciirq = 0;
} else if (!pciirq || pciirq >= NR_IRQS) {
printk("%s: bad irq from BIOS (%d): will probe later\n", d->name, pciirq);
pciirq = 0;
} else {
printk("%s: 100%% native mode on irq %d\n", d->name, pciirq);
}
/*
* Set up the IDE ports
......@@ -286,6 +300,7 @@ __initfunc(static void ide_setup_pci_device (byte bus, byte fn, unsigned int cco
hwif->pci_fn = fn;
hwif->pci_devid = d->devid;
hwif->channel = port;
if (!hwif->irq)
hwif->irq = pciirq;
if (mate) {
hwif->mate = mate;
......@@ -296,7 +311,7 @@ __initfunc(static void ide_setup_pci_device (byte bus, byte fn, unsigned int cco
#ifdef CONFIG_BLK_DEV_IDEDMA
if (IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20246) || ((ccode >> 16) == PCI_CLASS_STORAGE_IDE && (ccode & 0x8000))) {
unsigned int extra = (!mate && IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20246)) ? 16 : 0;
unsigned int dma_base = ide_get_or_set_dma_base(hwif, extra, d->name);
unsigned long dma_base = ide_get_or_set_dma_base(hwif, extra, d->name);
if (dma_base && !(pcicmd & 4)) {
/*
* Set up BM-DMA capability (PnP BIOS should have done this)
......@@ -311,7 +326,7 @@ __initfunc(static void ide_setup_pci_device (byte bus, byte fn, unsigned int cco
if (dma_base)
ide_setup_dma(hwif, dma_base, 8);
else
printk("%s: %s Bus-Master DMA disabled (BIOS), pcicmd=0x%04x, ccode=0x%04x, dma_base=0x%04x\n",
printk("%s: %s Bus-Master DMA disabled (BIOS), pcicmd=0x%04x, ccode=0x%04x, dma_base=0x%04lx\n",
hwif->name, d->name, pcicmd, ccode, dma_base);
}
#endif /* CONFIG_BLK_DEV_IDEDMA */
......@@ -352,10 +367,10 @@ static inline void ide_scan_pci_device (unsigned int bus, unsigned int fn)
continue; /* OPTI Viper-M uses same devid for functions 0 and 1 */
else if (!IDE_PCI_DEVID_EQ(d->devid, IDE_PCI_DEVID_NULL) || (ccode >> 16) == PCI_CLASS_STORAGE_IDE) {
if (IDE_PCI_DEVID_EQ(d->devid, IDE_PCI_DEVID_NULL))
printk("%s: unknown IDE device on PCI bus %d function %d, VID=%04x, DID=%04x\n",
printk("%s: unknown IDE controller on PCI bus %d function %d, VID=%04x, DID=%04x\n",
d->name, bus, fn, devid.vid, devid.did);
else
printk("%s: PCI bus %d function %d\n", d->name, bus, fn);
printk("%s: IDE controller on PCI bus %d function %d\n", d->name, bus, fn);
ide_setup_pci_device(bus, fn, ccode, d);
}
} while (hedt == 0x80 && (++fn & 7));
......@@ -379,4 +394,3 @@ void ide_scan_pcibus (void) /* __init */
}
}
}
/*
* linux/drivers/block/proc_ide.c Version 1.01 December 12, 1997
* linux/drivers/block/ide-proc.c Version 1.02 December 31, 1997
*
* Copyright (C) 1997-1998 Mark Lord
*/
......@@ -13,15 +13,30 @@
* This should provide better utilities, and less kernel bloat.
*
* The entire pci config space for a PCI interface chipset can be
* retrieved by just reading it. e.g. "cat /proc/ide3/pci"
* retrieved by just reading it. e.g. "cat /proc/ide3/config"
*
* To modify registers, do something like:
* echo "40:88" >/proc/ide/ide3/pci
* To modify registers *safely*, do something like:
* echo "P40:88" >/proc/ide/ide3/config
* That expression writes 0x88 to pci config register 0x40
* on the chip which controls ide3. Multiple tuples can be issued,
* and the writes will be completed as an atomic set:
* echo "40:88 41:35 42:00 43:00" >/proc/ide/ide3/pci
* All numbers must be pairs of ascii hex digits.
* echo "P40:88 P41:35 P42:00 P43:00" >/proc/ide/ide3/config
*
* All numbers must be specified using pairs of ascii hex digits.
* It is important to note that these writes will be performed
* after waiting for the IDE controller (both interfaces)
* to be completely idle, to ensure no corruption of I/O in progress.
*
* Non-PCI registers can also be written, using "R" in place of "P"
* in the above examples. The size of the port transfer is determined
* by the number of pairs of hex digits given for the data. If a two
* digit value is given, the write will be a byte operation; if four
* digits are used, the write will be performed as a 16-bit operation;
* and if eight digits are specified, a 32-bit "dword" write will be
* performed. Odd numbers of digits are not permitted.
*
* If there is an error *anywhere* in the string of registers/data
* then *none* of the writes will be performed.
*
* Also useful, "cat /proc/ide0/hda/identify" will issue an IDENTIFY
* (or PACKET_IDENTIFY) command to /dev/hda, and then dump out the
......@@ -44,6 +59,7 @@
#include <linux/pci.h>
#include <linux/bios32.h>
#include <linux/ctype.h>
#include <asm/io.h>
#include "ide.h"
#ifndef MIN
......@@ -64,13 +80,14 @@ static int ide_getxdigit(char c)
return digit;
}
static int xx_xx_parse_error (const char *start, unsigned long maxlen)
static int xx_xx_parse_error (const char *data, unsigned long len, const char *msg)
{
char errbuf[7];
int i, len = MIN(6, maxlen);
char errbuf[16];
int i;
if (len >= sizeof(errbuf))
len = sizeof(errbuf) - 1;
for (i = 0; i < len; ++i) {
char c = start[i];
char c = data[i];
if (!c || c == '\n')
c = '\0';
else if (iscntrl(c))
......@@ -78,17 +95,17 @@ static int xx_xx_parse_error (const char *start, unsigned long maxlen)
errbuf[i] = c;
}
errbuf[i] = '\0';
printk("proc_ide: error: expected 'xx:xx', but got '%s'\n", errbuf);
printk("proc_ide: error: %s: '%s'\n", msg, errbuf);
return -EINVAL;
}
static int proc_ide_write_pci
static int proc_ide_write_config
(struct file *file, const char *buffer, unsigned long count, void *data)
{
ide_hwif_t *hwif = (ide_hwif_t *)data;
int for_real = 0;
unsigned long n, flags;
const char *start;
unsigned long startn = 0, n, flags;
const char *start = NULL, *msg = NULL;
if (!suser())
return -EACCES;
......@@ -105,57 +122,110 @@ static int proc_ide_write_pci
*/
save_flags(flags);
do {
const char *p = buffer;
n = count;
const char *p;
if (for_real) {
unsigned long timeout = jiffies + (3 * HZ);
ide_hwgroup_t *mygroup = (ide_hwgroup_t *)(hwif->hwgroup);
ide_hwgroup_t *mategroup = NULL;
if (hwif->mate && hwif->mate->hwgroup)
mategroup = (ide_hwgroup_t *)(hwif->mate->hwgroup);
cli(); /* ensure all PCI writes are done together */
while (((ide_hwgroup_t *)(hwif->hwgroup))->active || (hwif->mate && ((ide_hwgroup_t *)(hwif->mate->hwgroup))->active)) {
sti();
while (mygroup->active || (mategroup && mategroup->active)) {
restore_flags(flags);
if (0 < (signed long)(jiffies - timeout)) {
printk("/proc/ide/%s/pci: channel(s) busy, cannot write\n", hwif->name);
restore_flags(flags);
return -EBUSY;
}
cli();
}
}
while (n) {
int d1, d2, rc;
byte reg, val;
p = buffer;
n = count;
while (n > 0) {
int d, digits;
unsigned int reg = 0, val = 0, is_pci;
start = p;
#if 0
printk("loop(%d): n=%ld, input=%.5s\n", for_real, n, p);
#endif
if (n < 5)
startn = n--;
switch (*p++) {
case 'R': is_pci = 0;
break;
case 'P': is_pci = 1;
break;
default: msg = "expected 'R' or 'P'";
goto parse_error;
if (0 > (d1 = ide_getxdigit(*p++)) || 0 > (d2 = ide_getxdigit(*p++)))
}
digits = 0;
while (n > 0 && (d = ide_getxdigit(*p)) >= 0) {
reg = (reg << 4) | d;
--n;
++p;
++digits;
}
if (!digits || (digits > 4) || (is_pci && reg > 0xff)) {
msg = "bad/missing register number";
goto parse_error;
reg = (d1 << 4) | d2;
if (*p++ != ':')
}
if (--n < 0 || *p++ != ':') {
msg = "missing ':'";
goto parse_error;
if (0 > (d1 = ide_getxdigit(*p++)) || 0 > (d2 = ide_getxdigit(*p++)))
}
digits = 0;
while (n > 0 && (d = ide_getxdigit(*p)) >= 0) {
val = (val << 4) | d;
--n;
++p;
++digits;
}
if (digits != 2 && digits != 4 && digits != 8) {
msg = "bad data, 2/4/8 digits required";
goto parse_error;
val = (d1 << 4) | d2;
if (n > 5 && !isspace(*p))
}
if (n > 0 && !isspace(*p)) {
msg = "expected whitespace after data";
goto parse_error;
n -= 5;
while (n && isspace(*p)) {
}
while (n > 0 && isspace(*p)) {
--n;
++p;
}
if (is_pci && (reg & ((digits >> 1) - 1))) {
msg = "misaligned access";
goto parse_error;
}
if (for_real) {
#if 0
printk("proc_ide_write_pci: reg=0x%02x, val=0x%02x\n", reg, val);
printk("proc_ide_write_config: type=%c, reg=0x%x, val=0x%x, digits=%d\n", is_pci ? 'PCI' : 'non-PCI', reg, val, digits);
#endif
if (is_pci) {
int rc = 0;
switch (digits) {
case 2: msg = "byte";
rc = pcibios_write_config_byte(hwif->pci_bus, hwif->pci_fn, reg, val);
break;
case 4: msg = "word";
rc = pcibios_write_config_word(hwif->pci_bus, hwif->pci_fn, reg, val);
break;
case 8: msg = "dword";
rc = pcibios_write_config_dword(hwif->pci_bus, hwif->pci_fn, reg, val);
break;
}
if (rc) {
restore_flags(flags);
printk("proc_ide_write_pci: error writing bus %d fn %d reg 0x%02x value 0x%02x\n",
hwif->pci_bus, hwif->pci_fn, reg, val);
printk("proc_ide_write_pci: %s\n", pcibios_strerror(rc));
printk("proc_ide_write_config: error writing %s at bus %d fn %d reg 0x%x value 0x%x\n",
msg, hwif->pci_bus, hwif->pci_fn, reg, val);
printk("proc_ide_write_config: %s\n", pcibios_strerror(rc));
return -EIO;
}
} else { /* not pci */
switch (digits) {
case 2: outb(val, reg);
break;
case 4: outw(val, reg);
break;
case 8: outl(val, reg);
break;
}
}
}
}
} while (!for_real++);
......@@ -163,25 +233,26 @@ static int proc_ide_write_pci
return count;
parse_error:
restore_flags(flags);
return xx_xx_parse_error(start, n);
printk("parse error\n");
return xx_xx_parse_error(start, startn, msg);
}
static int proc_ide_read_pci
static int proc_ide_read_config
(char *page, char **start, off_t off, int count, int *eof, void *data)
{
ide_hwif_t *hwif = (ide_hwif_t *)data;
char *out = page;
int len, reg = 0;
out += sprintf(out, "Bus %d Function %d Vendor %04x Device %04x Channel %d\n",
out += sprintf(out, "pci bus %d function %d vendor %04x device %04x channel %d\n",
hwif->pci_bus, hwif->pci_fn, hwif->pci_devid.vid, hwif->pci_devid.did, hwif->channel);
do {
byte val;
int rc = pcibios_read_config_byte(hwif->pci_bus, hwif->pci_fn, reg, &val);
if (rc) {
printk("proc_ide_read_pci: error reading bus %d fn %d reg 0x%02x\n",
printk("proc_ide_read_config: error reading bus %d fn %d reg 0x%02x\n",
hwif->pci_bus, hwif->pci_fn, reg);
printk("proc_ide_read_pci: %s\n", pcibios_strerror(rc));
printk("proc_ide_read_config: %s\n", pcibios_strerror(rc));
return -EIO;
out += sprintf(out, "??%c", (++reg & 0xf) ? ' ' : '\n');
} else
......@@ -455,11 +526,11 @@ static void create_proc_ide_interfaces (struct proc_dir_entry *parent)
if (!hwif_ent) return;
#ifdef CONFIG_PCI
if (!IDE_PCI_DEVID_EQ(hwif->pci_devid, IDE_PCI_DEVID_NULL)) {
ent = create_proc_entry("pci", 0, hwif_ent);
ent = create_proc_entry("config", 0, hwif_ent);
if (!ent) return;
ent->data = hwif;
ent->read_proc = proc_ide_read_pci;
ent->write_proc = proc_ide_write_pci;;
ent->read_proc = proc_ide_read_config;
ent->write_proc = proc_ide_write_config;;
ent = create_proc_entry("model", 0, hwif_ent);
if (!ent) return;
......
......@@ -321,9 +321,9 @@ typedef struct hwif_s {
ide_dmaproc_t *dmaproc; /* dma read/write/abort routine */
unsigned long *dmatable; /* dma physical region descriptor table */
struct hwif_s *mate; /* other hwif from same PCI chip */
unsigned int dma_base; /* base addr for dma ports */
unsigned int config_data; /* for use by chipset-specific code */
unsigned int select_data; /* for use by chipset-specific code */
unsigned long dma_base; /* base addr for dma ports */
unsigned long config_data; /* for use by chipset-specific code */
unsigned long select_data; /* for use by chipset-specific code */
struct proc_dir_entry *proc; /* /proc/ide/ directory entry */
int irq; /* our irq number */
byte major; /* our major number */
......@@ -365,7 +365,7 @@ typedef struct hwgroup_s {
* /proc/ide interface
*/
typedef struct {
char *name;
const char *name;
read_proc_t *read_proc;
write_proc_t *write_proc;
} ide_proc_entry_t;
......@@ -656,15 +656,15 @@ int ide_register_subdriver (ide_drive_t *drive, ide_driver_t *driver, int versio
int ide_unregister_subdriver (ide_drive_t *drive);
#ifdef CONFIG_BLK_DEV_IDEPCI
unsigned int ide_find_free_region (unsigned short size) __init;
unsigned long ide_find_free_region (unsigned short size) __init;
void ide_scan_pcibus (void) __init;
#endif
#ifdef CONFIG_BLK_DEV_IDEDMA
int ide_build_dmatable (ide_drive_t *drive);
void ide_dma_intr (ide_drive_t *drive);
int ide_dmaproc (ide_dma_action_t func, ide_drive_t *drive);
void ide_setup_dma (ide_hwif_t *hwif, unsigned int dmabase, unsigned int num_ports) __init;
unsigned int ide_get_or_set_dma_base (ide_hwif_t *hwif, int extra, const char *name) __init;
void ide_setup_dma (ide_hwif_t *hwif, unsigned long dmabase, unsigned int num_ports) __init;
unsigned long ide_get_or_set_dma_base (ide_hwif_t *hwif, int extra, const char *name) __init;
#endif
#ifdef CONFIG_BLK_DEV_IDE
......
......@@ -15,7 +15,7 @@
* breaking the fragile cmd640.c support.
*/
#if defined(CONFIG_BLK_DEV_CMD640) || defined(CONFIG_IDE_CHIPSETS)
#if defined(CONFIG_BLK_DEV_CMD640) || defined(CONFIG_IDE_CHIPSETS) || defined(CONFIG_BLK_DEV_OPTI621)
/*
* Standard (generic) timings for PIO modes, from ATA2 specification.
......@@ -222,5 +222,5 @@ byte ide_get_best_pio_mode (ide_drive_t *drive, byte mode_wanted, byte max_mode,
}
#endif /* _IDE_C */
#endif /* defined(CONFIG_BLK_DEV_CMD640) || defined(CONFIG_IDE_CHIPSETS) */
#endif /* defined(CONFIG_BLK_DEV_CMD640) || defined(CONFIG_IDE_CHIPSETS) || defined(CONFIG_BLK_DEV_OPTI621) */
#endif /* _IDE_MODES_H */
......@@ -665,12 +665,6 @@ void ll_rw_swap_file(int rw, kdev_t dev, unsigned int *b, int nb, char *buf)
}
}
}
#ifdef CONFIG_BLK_DEV_EZ
extern void ez_init( void );
#endif
#ifdef CONFIG_BPCD
extern void bpcd_init( void );
#endif
__initfunc(int blk_dev_init(void))
{
......@@ -724,8 +718,8 @@ __initfunc(int blk_dev_init(void))
#ifdef CONFIG_BLK_DEV_XD
xd_init();
#endif
#ifdef CONFIG_BLK_DEV_EZ
ez_init();
#ifdef CONFIG_PARIDE
{ extern void paride_init(void); paride_init(); };
#endif
#ifdef CONFIG_MAC_FLOPPY
swim3_init();
......@@ -761,9 +755,6 @@ __initfunc(int blk_dev_init(void))
#ifdef CONFIG_GSCD
gscd_init();
#endif CONFIG_GSCD
#ifdef CONFIG_BPCD
bpcd_init();
#endif CONFIG_BPCD
#ifdef CONFIG_CM206
cm206_init();
#endif
......
#
# PARIDE configuration
#
comment 'Parallel IDE high-level drivers'
dep_tristate ' Parallel port IDE disks' CONFIG_PARIDE_PD $CONFIG_PARIDE
dep_tristate ' Parallel port ATAPI CD-ROMs' CONFIG_PARIDE_PCD $CONFIG_PARIDE
dep_tristate ' Parallel port ATAPI disks' CONFIG_PARIDE_PF $CONFIG_PARIDE
comment 'Parallel IDE protocol modules'
dep_tristate ' ATEN EH-100 protocol' CONFIG_PARIDE_ATEN $CONFIG_PARIDE
dep_tristate ' MicroSolutions backpack protocol' CONFIG_PARIDE_BPCK $CONFIG_PARIDE
dep_tristate ' DataStor Commuter protocol' CONFIG_PARIDE_COMM $CONFIG_PARIDE
dep_tristate ' DataStor EP-2000 protocol' CONFIG_PARIDE_DSTR $CONFIG_PARIDE
dep_tristate ' Shuttle EPAT/EPEZ protocol' CONFIG_PARIDE_EPAT $CONFIG_PARIDE
dep_tristate ' Shuttle EPIA protocol' CONFIG_PARIDE_EPIA $CONFIG_PARIDE
dep_tristate ' FreeCom power protocol' CONFIG_PARIDE_FRPW $CONFIG_PARIDE
dep_tristate ' KingByte KBIC-951A/971A protocols' CONFIG_PARIDE_KBIC $CONFIG_PARIDE
dep_tristate ' OnSpec 90c20 protocol' CONFIG_PARIDE_ON20 $CONFIG_PARIDE
dep_tristate ' OnSpec 90c26 protocol' CONFIG_PARIDE_ON26 $CONFIG_PARIDE
#
#
# Makefile for PARIDE
#
# Note! Dependencies are done automagically by 'make dep', which also
# removes any old dependencies. DON'T put your own dependencies here
# unless it's something special (ie not a .c file).
#
# Note 2! The CFLAGS definitions are now inherited from the
# parent makes..
SUB_DIRS :=
MOD_SUB_DIRS := $(SUB_DIRS)
ALL_SUB_DIRS := $(SUB_DIRS)
L_TARGET := paride.a
MX_OBJS :=
LX_OBJS :=
MI_OBJS :=
MIX_OBJS :=
ifeq ($(CONFIG_PARIDE),y)
LX_OBJS += paride.o
else
ifeq ($(CONFIG_PARIDE),m)
MX_OBJS += paride.o
endif
endif
ifeq ($(CONFIG_PARIDE_PD),y)
LX_OBJS += pd.o
else
ifeq ($(CONFIG_PARIDE_PD),m)
MX_OBJS += pd.o
endif
endif
ifeq ($(CONFIG_PARIDE_PCD),y)
LX_OBJS += pcd.o
else
ifeq ($(CONFIG_PARIDE_PCD),m)
MX_OBJS += pcd.o
endif
endif
ifeq ($(CONFIG_PARIDE_PF),y)
LX_OBJS += pf.o
else
ifeq ($(CONFIG_PARIDE_PF),m)
MX_OBJS += pf.o
endif
endif
ifeq ($(CONFIG_PARIDE_ATEN),y)
LX_OBJS += aten.o
else
ifeq ($(CONFIG_PARIDE_ATEN),m)
MX_OBJS += aten.o
endif
endif
ifeq ($(CONFIG_PARIDE_BPCK),y)
LX_OBJS += bpck.o
else
ifeq ($(CONFIG_PARIDE_BPCK),m)
MX_OBJS += bpck.o
endif
endif
ifeq ($(CONFIG_PARIDE_COMM),y)
LX_OBJS += comm.o
else
ifeq ($(CONFIG_PARIDE_COMM),m)
MX_OBJS += comm.o
endif
endif
ifeq ($(CONFIG_PARIDE_DSTR),y)
LX_OBJS += dstr.o
else
ifeq ($(CONFIG_PARIDE_DSTR),m)
MX_OBJS += dstr.o
endif
endif
ifeq ($(CONFIG_PARIDE_KBIC),y)
LX_OBJS += kbic.o
else
ifeq ($(CONFIG_PARIDE_KBIC),m)
MX_OBJS += kbic.o
endif
endif
ifeq ($(CONFIG_PARIDE_EPAT),y)
LX_OBJS += epat.o
else
ifeq ($(CONFIG_PARIDE_EPAT),m)
MX_OBJS += epat.o
endif
endif
ifeq ($(CONFIG_PARIDE_EPIA),y)
LX_OBJS += epia.o
else
ifeq ($(CONFIG_PARIDE_EPIA),m)
MX_OBJS += epia.o
endif
endif
ifeq ($(CONFIG_PARIDE_FRPW),y)
LX_OBJS += frpw.o
else
ifeq ($(CONFIG_PARIDE_FRPW),m)
MX_OBJS += frpw.o
endif
endif
ifeq ($(CONFIG_PARIDE_ON20),y)
LX_OBJS += on20.o
else
ifeq ($(CONFIG_PARIDE_ON20),m)
MX_OBJS += on20.o
endif
endif
ifeq ($(CONFIG_PARIDE_ON26),y)
LX_OBJS += on26.o
else
ifeq ($(CONFIG_PARIDE_ON26),m)
MX_OBJS += on26.o
endif
endif
include $(TOPDIR)/Rules.make
/*
aten.c (c) 1997 Grant R. Guenther <grant@torque.net>
Under the terms of the GNU public license.
aten.c is a low-level protocol driver for the ATEN EH-100
parallel port adapter. The EH-100 supports 4-bit and 8-bit
modes only. There is also an EH-132 which supports EPP mode
transfers. The EH-132 is not yet supported.
*/
#define ATEN_VERSION "1.0"
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <asm/io.h>
#include "paride.h"
#define j44(a,b) ((((a>>4)&0x0f)|(b&0xf0))^0x88)
/* cont = 0 - access the IDE register file
cont = 1 - access the IDE command set
*/
static int cont_map[2] = { 0x08, 0x20 };
static void aten_write_regr( PIA *pi, int cont, int regr, int val)
{ int r;
r = regr + cont_map[cont] + 0x80;
w0(r); w2(0xe); w2(6); w0(val); w2(7); w2(6); w2(0xc);
}
static int aten_read_regr( PIA *pi, int cont, int regr )
{ int a, b, r;
r = regr + cont_map[cont] + 0x40;
switch (pi->mode) {
case 0: w0(r); w2(0xe); w2(6);
w2(7); w2(6); w2(0);
a = r1(); w0(0x10); b = r1(); w2(0xc);
return j44(a,b);
case 1: r |= 0x10;
w0(r); w2(0xe); w2(6); w0(0xff);
w2(0x27); w2(0x26); w2(0x20);
a = r0();
w2(0x26); w2(0xc);
return a;
}
return -1;
}
static void aten_read_block( PIA *pi, char * buf, int count )
{ int k, a, b, c, d;
switch (pi->mode) {
case 0: w0(0x48); w2(0xe); w2(6);
for (k=0;k<count/2;k++) {
w2(7); w2(6); w2(2);
a = r1(); w0(0x58); b = r1();
w2(0); d = r1(); w0(0x48); c = r1();
buf[2*k] = j44(c,d);
buf[2*k+1] = j44(a,b);
}
w2(0xc);
break;
case 1: w0(0x58); w2(0xe); w2(6);
for (k=0;k<count/2;k++) {
w2(0x27); w2(0x26); w2(0x22);
a = r0(); w2(0x20); b = r0();
buf[2*k] = b; buf[2*k+1] = a;
}
w2(0x26); w2(0xc);
break;
}
}
static void aten_write_block( PIA *pi, char * buf, int count )
{ int k;
w0(0x88); w2(0xe); w2(6);
for (k=0;k<count/2;k++) {
w0(buf[2*k+1]); w2(0xe); w2(6);
w0(buf[2*k]); w2(7); w2(6);
}
w2(0xc);
}
static void aten_connect ( PIA *pi )
{ pi->saved_r0 = r0();
pi->saved_r2 = r2();
w2(0xc);
}
static void aten_disconnect ( PIA *pi )
{ w0(pi->saved_r0);
w2(pi->saved_r2);
}
static void aten_log_adapter( PIA *pi, char * scratch, int verbose )
{ char *mode_string[2] = {"4-bit","8-bit"};
printk("%s: aten %s, ATEN EH-100 at 0x%x, ",
pi->device,ATEN_VERSION,pi->port);
printk("mode %d (%s), delay %d\n",pi->mode,
mode_string[pi->mode],pi->delay);
}
static void aten_inc_use ( void )
{ MOD_INC_USE_COUNT;
}
static void aten_dec_use ( void )
{ MOD_DEC_USE_COUNT;
}
struct pi_protocol aten = {"aten",0,2,2,1,1,
aten_write_regr,
aten_read_regr,
aten_write_block,
aten_read_block,
aten_connect,
aten_disconnect,
0,
0,
0,
aten_log_adapter,
aten_inc_use,
aten_dec_use
};
#ifdef MODULE
int init_module(void)
{ return pi_register( &aten ) - 1;
}
void cleanup_module(void)
{ pi_unregister( &aten );
}
#endif
/* end of aten.c */
/*
bpck.c (c) 1996,1997 Grant R. Guenther <grant@torque.net>
Under the terms of the GNU public license.
bpck.c is a low-level protocol driver for the MicroSolutions
"backpack" parallel port IDE adapter.
*/
#define BPCK_VERSION "1.0"
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <asm/io.h>
#include "paride.h"
#undef r2
#undef w2
#define PC pi->private
#define r2() (PC=(in_p(2) & 0xff))
#define w2(byte) {out_p(2,byte); PC = byte;}
#define t2(pat) {PC ^= pat; out_p(2,PC);}
#define e2() {PC &= 0xfe; out_p(2,PC);}
#define o2() {PC |= 1; out_p(2,PC);}
#define j44(l,h) (((l>>3)&0x7)|((l>>4)&0x8)|((h<<1)&0x70)|(h&0x80))
/* cont = 0 - access the IDE register file
cont = 1 - access the IDE command set
cont = 2 - use internal bpck register addressing
*/
static int cont_map[3] = { 0x40, 0x48, 0 };
static int bpck_read_regr( PIA *pi, int cont, int regr )
{ int r, l, h;
r = regr + cont_map[cont];
switch (pi->mode) {
case 0: w0(r & 0xf); w0(r); t2(2); t2(4);
l = r1();
t2(4);
h = r1();
return j44(l,h);
case 1: w0(r & 0xf); w0(r); t2(2);
e2(); t2(0x20);
t2(4); h = r0();
t2(1); t2(0x20);
return h;
case 2:
case 3:
case 4: w0(r); w2(9); w2(0); w2(0x20);
h = r4();
w2(0);
return h;
}
return -1;
}
static void bpck_write_regr( PIA *pi, int cont, int regr, int val )
{ int r;
r = regr + cont_map[cont];
switch (pi->mode) {
case 0:
case 1: w0(r);
t2(2);
w0(val);
o2(); t2(4); t2(1);
break;
case 2:
case 3:
case 4: w0(r); w2(9); w2(0);
w0(val); w2(1); w2(3); w2(0);
break;
}
}
/* These macros access the bpck registers in native addressing */
#define WR(r,v) bpck_write_regr(pi,2,r,v)
#define RR(r) (bpck_read_regr(pi,2,r))
static void bpck_write_block( PIA *pi, char * buf, int count )
{ int i;
switch (pi->mode) {
case 0: WR(4,0x40);
w0(0x40); t2(2); t2(1);
for (i=0;i<count;i++) { w0(buf[i]); t2(4); }
WR(4,0);
break;
case 1: WR(4,0x50);
w0(0x40); t2(2); t2(1);
for (i=0;i<count;i++) { w0(buf[i]); t2(4); }
WR(4,0x10);
break;
case 2: WR(4,0x48);
w0(0x40); w2(9); w2(0); w2(1);
for (i=0;i<count;i++) w4(buf[i]);
w2(0);
WR(4,8);
break;
case 3: WR(4,0x48);
w0(0x40); w2(9); w2(0); w2(1);
for (i=0;i<count/2;i++) w4w(((u16 *)buf)[i]);
w2(0);
WR(4,8);
break;
case 4: WR(4,0x48);
w0(0x40); w2(9); w2(0); w2(1);
for (i=0;i<count/4;i++) w4l(((u32 *)buf)[i]);
w2(0);
WR(4,8);
break;
}
}
static void bpck_read_block( PIA *pi, char * buf, int count )
{ int i, l, h;
switch (pi->mode) {
case 0: WR(4,0x40);
w0(0x40); t2(2);
for (i=0;i<count;i++) {
t2(4); l = r1();
t2(4); h = r1();
buf[i] = j44(l,h);
}
WR(4,0);
break;
case 1: WR(4,0x50);
w0(0x40); t2(2); t2(0x20);
for(i=0;i<count;i++) { t2(4); buf[i] = r0(); }
t2(1); t2(0x20);
WR(4,0x10);
break;
case 2: WR(4,0x48);
w0(0x40); w2(9); w2(0); w2(0x20);
for (i=0;i<count;i++) buf[i] = r4();
w2(0);
WR(4,8);
break;
case 3: WR(4,0x48);
w0(0x40); w2(9); w2(0); w2(0x20);
for (i=0;i<count/2;i++) ((u16 *)buf)[i] = r4w();
w2(0);
WR(4,8);
break;
case 4: WR(4,0x48);
w0(0x40); w2(9); w2(0); w2(0x20);
for (i=0;i<count/4;i++) ((u32 *)buf)[i] = r4l();
w2(0);
WR(4,8);
break;
}
}
static int bpck_probe_unit ( PIA *pi )
{ int o1, o0, f7, id;
int t, s;
id = pi->unit;
s = 0;
w2(4); w2(0xe); r2(); t2(2);
o1 = r1()&0xf8;
o0 = r0();
w0(255-id); w2(4); w0(id);
t2(8); t2(8); t2(8);
t2(2); t = r1()&0xf8;
f7 = ((id % 8) == 7);
if ((f7) || (t != o1)) { t2(2); s = r1()&0xf8; }
if ((t == o1) && ((!f7) || (s == o1))) {
w2(0x4c); w0(o0);
return 0;
}
t2(8); w0(0); t2(2); w2(0x4c); w0(o0);
return 1;
}
static void bpck_connect ( PIA *pi )
{ pi->saved_r0 = r0();
w0(0xff-pi->unit); w2(4); w0(pi->unit);
t2(8); t2(8); t2(8);
t2(2); t2(2);
switch (pi->mode) {
case 0: t2(8); WR(4,0);
break;
case 1: t2(8); WR(4,0x10);
break;
case 2:
case 3:
case 4: w2(0); WR(4,8);
break;
}
WR(5,8);
if (pi->devtype == PI_PCD) {
WR(0x46,0x10); /* fiddle with ESS logic ??? */
WR(0x4c,0x38);
WR(0x4d,0x88);
WR(0x46,0xa0);
WR(0x41,0);
WR(0x4e,8);
}
}
static void bpck_disconnect ( PIA *pi )
{ w0(0);
if (pi->mode >= 2) { w2(9); w2(0); } else t2(2);
w2(0x4c); w0(pi->saved_r0);
}
static void bpck_force_spp ( PIA *pi )
/* This fakes the EPP protocol to turn off EPP ... */
{ pi->saved_r0 = r0();
w0(0xff-pi->unit); w2(4); w0(pi->unit);
t2(8); t2(8); t2(8);
t2(2); t2(2);
w2(0);
w0(4); w2(9); w2(0);
w0(0); w2(1); w2(3); w2(0);
w0(0); w2(9); w2(0);
w2(0x4c); w0(pi->saved_r0);
}
#define TEST_LEN 16
static int bpck_test_proto( PIA *pi, char * scratch, int verbose )
{ int i, e, l, h, om;
char buf[TEST_LEN];
bpck_force_spp(pi);
switch (pi->mode) {
case 0: bpck_connect(pi);
WR(0x13,0x7f);
w0(0x13); t2(2);
for(i=0;i<TEST_LEN;i++) {
t2(4); l = r1();
t2(4); h = r1();
buf[i] = j44(l,h);
}
bpck_disconnect(pi);
break;
case 1: bpck_connect(pi);
WR(0x13,0x7f);
w0(0x13); t2(2); t2(0x20);
for(i=0;i<TEST_LEN;i++) { t2(4); buf[i] = r0(); }
t2(1); t2(0x20);
bpck_disconnect(pi);
break;
case 2:
case 3:
case 4: om = pi->mode;
pi->mode = 0;
bpck_connect(pi);
WR(7,3);
WR(4,8);
bpck_disconnect(pi);
pi->mode = om;
bpck_connect(pi);
w0(0x13); w2(9); w2(1); w0(0); w2(3); w2(0); w2(0xe0);
switch (pi->mode) {
case 2: for (i=0;i<TEST_LEN;i++) buf[i] = r4();
break;
case 3: for (i=0;i<TEST_LEN/2;i++) ((u16 *)buf)[i] = r4w();
break;
case 4: for (i=0;i<TEST_LEN/4;i++) ((u32 *)buf)[i] = r4l();
break;
}
w2(0);
WR(7,0);
bpck_disconnect(pi);
break;
}
if (verbose) {
printk("%s: bpck: 0x%x unit %d mode %d: ",
pi->device,pi->port,pi->unit,pi->mode);
for (i=0;i<TEST_LEN;i++) printk("%3d",buf[i]);
printk("\n");
}
e = 0;
for (i=0;i<TEST_LEN;i++) if (buf[i] != (i+1)) e++;
return e;
}
static void bpck_read_eeprom ( PIA *pi, char * buf )
{ int i,j,k,n,p,v,f, om;
bpck_force_spp(pi);
om = pi->mode;
pi->mode = 0;
bpck_connect(pi);
n = 0;
WR(4,0);
for (i=0;i<64;i++) {
WR(6,8);
WR(6,0xc);
p = 0x100;
for (k=0;k<9;k++) {
f = (((i + 0x180) & p) != 0) * 2;
WR(6,f+0xc);
WR(6,f+0xd);
WR(6,f+0xc);
p = (p >> 1);
}
for (j=0;j<2;j++) {
v = 0;
for (k=0;k<8;k++) {
WR(6,0xc);
WR(6,0xd);
WR(6,0xc);
f = RR(0);
v = 2*v + (f == 0x84);
}
buf[2*i+1-j] = v;
}
}
WR(6,8);
WR(6,0);
WR(5,8);
bpck_disconnect(pi);
if (om >= 2) {
bpck_connect(pi);
WR(7,3);
WR(4,8);
bpck_disconnect(pi);
}
pi->mode = om;
}
static int bpck_test_port ( PIA *pi ) /* check for 8-bit port */
{ int i, r, m;
w2(0x2c); i = r0(); w0(255-i); r = r0(); w0(i);
m = -1;
if (r == i) m = 2;
if (r == (255-i)) m = 0;
w2(0xc); i = r0(); w0(255-i); r = r0(); w0(i);
if (r != (255-i)) m = -1;
if (m == 0) { w2(6); w2(0xc); r = r0(); w0(0xaa); w0(r); w0(0xaa); }
if (m == 2) { w2(0x26); w2(0xc); }
if (m == -1) return 0;
return 5;
}
static void bpck_log_adapter( PIA *pi, char * scratch, int verbose )
{ char *mode_string[5] = { "4-bit","8-bit","EPP-8",
"EPP-16","EPP-32" };
#ifdef DUMP_EEPROM
int i;
#endif
bpck_read_eeprom(pi,scratch);
#ifdef DUMP_EEPROM
if (verbose) {
for(i=0;i<128;i++)
if ((scratch[i] < ' ') || (scratch[i] > '~'))
scratch[i] = '.';
printk("%s: bpck EEPROM: %64.64s\n",pi->device,scratch);
printk("%s: %64.64s\n",pi->device,&scratch[64]);
}
#endif
printk("%s: bpck %s, backpack %8.8s unit %d",
pi->device,BPCK_VERSION,&scratch[110],pi->unit);
printk(" at 0x%x, mode %d (%s), delay %d\n",pi->port,
pi->mode,mode_string[pi->mode],pi->delay);
}
static void bpck_inc_use( void )
{ MOD_INC_USE_COUNT;
}
static void bpck_dec_use( void )
{ MOD_DEC_USE_COUNT;
}
struct pi_protocol bpck = { "bpck",0,5,2,4,256,
bpck_write_regr,
bpck_read_regr,
bpck_write_block,
bpck_read_block,
bpck_connect,
bpck_disconnect,
bpck_test_port,
bpck_probe_unit,
bpck_test_proto,
bpck_log_adapter,
bpck_inc_use,
bpck_dec_use
};
#ifdef MODULE
int init_module(void)
{ return pi_register(&bpck) - 1;
}
void cleanup_module(void)
{ pi_unregister(&bpck);
}
#endif
/* end of bpck.c */
/*
comm.c (c) 1997 Grant R. Guenther <grant@torque.net>
Under the terms of the GNU public license.
comm.c is a low-level protocol driver for some older models
of the DataStor "Commuter" parallel to IDE adapter. Some of
the parallel port devices marketed by Arista currently
use this adapter.
*/
#define COMM_VERSION "1.0"
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <asm/io.h>
#include "paride.h"
/* mode codes: 0 nybble reads, 8-bit writes
1 8-bit reads and writes
2 8-bit EPP mode
*/
#define j44(a,b) (((a>>3)&0x0f)|((b<<1)&0xf0))
#define P1 w2(5);w2(0xd);w2(0xd);w2(5);w2(4);
#define P2 w2(5);w2(7);w2(7);w2(5);w2(4);
/* cont = 0 - access the IDE register file
cont = 1 - access the IDE command set
*/
static int cont_map[2] = { 0x08, 0x10 };
static int comm_read_regr( PIA *pi, int cont, int regr )
{ int l, h, r;
r = regr + cont_map[cont];
switch (pi->mode) {
case 0: w0(r); P1; w0(0);
w2(6); l = r1(); w0(0x80); h = r1(); w2(4);
return j44(l,h);
case 1: w0(r+0x20); P1;
w0(0); w2(0x26); h = r0(); w2(4);
return h;
case 2:
case 3:
case 4: w3(r+0x20); r1();
w2(0x24); h = r4(); w2(4);
return h;
}
return -1;
}
static void comm_write_regr( PIA *pi, int cont, int regr, int val )
{ int r;
r = regr + cont_map[cont];
switch (pi->mode) {
case 0:
case 1: w0(r); P1; w0(val); P2;
break;
case 2:
case 3:
case 4: w3(r); r1(); w4(val);
break;
}
}
static void comm_connect ( PIA *pi )
{ pi->saved_r0 = r0();
pi->saved_r2 = r2();
w2(4); w0(0xff); w2(6);
w2(4); w0(0xaa); w2(6);
w2(4); w0(0x00); w2(6);
w2(4); w0(0x87); w2(6);
w2(4); w0(0xe0); w2(0xc); w2(0xc); w2(4);
}
static void comm_disconnect ( PIA *pi )
{ w2(0); w2(0); w2(0); w2(4);
w0(pi->saved_r0);
w2(pi->saved_r2);
}
static void comm_read_block( PIA *pi, char * buf, int count )
{ int i, l, h;
switch (pi->mode) {
case 0: w0(0x48); P1;
for(i=0;i<count;i++) {
w0(0); w2(6); l = r1();
w0(0x80); h = r1(); w2(4);
buf[i] = j44(l,h);
}
break;
case 1: w0(0x68); P1; w0(0);
for(i=0;i<count;i++) {
w2(0x26); buf[i] = r0(); w2(0x24);
}
w2(4);
break;
case 2: w3(0x68); r1(); w2(0x24);
for (i=0;i<count;i++) buf[i] = r4();
w2(4);
break;
case 3: w3(0x68); r1(); w2(0x24);
for (i=0;i<count/2;i++) ((u16 *)buf)[i] = r4w();
w2(4);
break;
case 4: w3(0x68); r1(); w2(0x24);
for (i=0;i<count/4;i++) ((u32 *)buf)[i] = r4l();
w2(4);
break;
}
}
/* NB: Watch out for the byte swapped writes ! */
static void comm_write_block( PIA *pi, char * buf, int count )
{ int k;
switch (pi->mode) {
case 0:
case 1: w0(0x68); P1;
for (k=0;k<count;k++) {
w2(5); w0(buf[k^1]); w2(7);
}
w2(5); w2(4);
break;
case 2: w3(0x48); r1();
for (k=0;k<count;k++) w4(buf[k^1]);
break;
case 3: w3(0x48); r1();
for (k=0;k<count/2;k++) w4w(pi_swab16(buf,k));
break;
case 4: w3(0x48); r1();
for (k=0;k<count/4;k++) w4l(pi_swab32(buf,k));
break;
}
}
static void comm_log_adapter( PIA *pi, char * scratch, int verbose )
{ char *mode_string[5] = {"4-bit","8-bit","EPP-8","EPP-16","EPP-32"};
printk("%s: comm %s, DataStor Commuter at 0x%x, ",
pi->device,COMM_VERSION,pi->port);
printk("mode %d (%s), delay %d\n",pi->mode,
mode_string[pi->mode],pi->delay);
}
static void comm_inc_use ( void )
{ MOD_INC_USE_COUNT;
}
static void comm_dec_use ( void )
{ MOD_DEC_USE_COUNT;
}
struct pi_protocol comm = {"comm",0,5,2,1,1,
comm_write_regr,
comm_read_regr,
comm_write_block,
comm_read_block,
comm_connect,
comm_disconnect,
0,
0,
0,
comm_log_adapter,
comm_inc_use,
comm_dec_use
};
#ifdef MODULE
int init_module(void)
{ return pi_register( &comm ) - 1;
}
void cleanup_module(void)
{ pi_unregister( &comm );
}
#endif
/* end of comm.c */
/*
dstr.c (c) 1997 Grant R. Guenther <grant@torque.net>
Under the terms of the GNU public license.
dstr.c is a low-level protocol driver for the
DataStor EP2000 parallel to IDE adapter chip.
*/
#define DSTR_VERSION "1.0"
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <asm/io.h>
#include "paride.h"
/* mode codes: 0 nybble reads, 8-bit writes
1 8-bit reads and writes
2 8-bit EPP mode
3 EPP-16
4 EPP-32
*/
#define j44(a,b) (((a>>3)&0x07)|((~a>>4)&0x08)|((b<<1)&0x70)|((~b)&0x80))
#define P1 w2(5);w2(0xd);w2(5);w2(4);
#define P2 w2(5);w2(7);w2(5);w2(4);
#define P3 w2(6);w2(4);w2(6);w2(4);
/* cont = 0 - access the IDE register file
cont = 1 - access the IDE command set
*/
static int cont_map[2] = { 0x20, 0x40 };
static int dstr_read_regr( PIA *pi, int cont, int regr )
{ int a, b, r;
r = regr + cont_map[cont];
w0(0x81); P1;
if (pi->mode) { w0(0x11); } else { w0(1); }
P2; w0(r); P1;
switch (pi->mode) {
case 0: w2(6); a = r1(); w2(4); w2(6); b = r1(); w2(4);
return j44(a,b);
case 1: w0(0); w2(0x26); a = r0(); w2(4);
return a;
case 2:
case 3:
case 4: w2(0x24); a = r4(); w2(4);
return a;
}
return -1;
}
static void dstr_write_regr( PIA *pi, int cont, int regr, int val )
{ int r;
r = regr + cont_map[cont];
w0(0x81); P1;
if (pi->mode >= 2) { w0(0x11); } else { w0(1); }
P2; w0(r); P1;
switch (pi->mode) {
case 0:
case 1: w0(val); w2(5); w2(7); w2(5); w2(4);
break;
case 2:
case 3:
case 4: w4(val);
break;
}
}
#define CCP(x) w0(0xff);w2(0xc);w2(4);\
w0(0xaa);w0(0x55);w0(0);w0(0xff);w0(0x87);w0(0x78);\
w0(x);w2(5);w2(4);
static void dstr_connect ( PIA *pi )
{ pi->saved_r0 = r0();
pi->saved_r2 = r2();
w2(4); CCP(0xe0); w0(0xff);
}
static void dstr_disconnect ( PIA *pi )
{ CCP(0x30);
w0(pi->saved_r0);
w2(pi->saved_r2);
}
static void dstr_read_block( PIA *pi, char * buf, int count )
{ int k, a, b;
w0(0x81); P1;
if (pi->mode) { w0(0x19); } else { w0(9); }
P2; w0(0x82); P1; P3; w0(0x20); P1;
switch (pi->mode) {
case 0: for (k=0;k<count;k++) {
w2(6); a = r1(); w2(4);
w2(6); b = r1(); w2(4);
buf[k] = j44(a,b);
}
break;
case 1: w0(0);
for (k=0;k<count;k++) {
w2(0x26); buf[k] = r0(); w2(0x24);
}
w2(4);
break;
case 2: w2(0x24);
for (k=0;k<count;k++) buf[k] = r4();
w2(4);
break;
case 3: w2(0x24);
for (k=0;k<count/2;k++) ((u16 *)buf)[k] = r4w();
w2(4);
break;
case 4: w2(0x24);
for (k=0;k<count/4;k++) ((u32 *)buf)[k] = r4l();
w2(4);
break;
}
}
static void dstr_write_block( PIA *pi, char * buf, int count )
{ int k;
w0(0x81); P1;
if (pi->mode) { w0(0x19); } else { w0(9); }
P2; w0(0x82); P1; P3; w0(0x20); P1;
switch (pi->mode) {
case 0:
case 1: for (k=0;k<count;k++) {
w2(5); w0(buf[k]); w2(7);
}
w2(5); w2(4);
break;
case 2: w2(0xc5);
for (k=0;k<count;k++) w4(buf[k]);
w2(0xc4);
break;
case 3: w2(0xc5);
for (k=0;k<count/2;k++) w4w(((u16 *)buf)[k]);
w2(0xc4);
break;
case 4: w2(0xc5);
for (k=0;k<count/4;k++) w4l(((u32 *)buf)[k]);
w2(0xc4);
break;
}
}
static void dstr_log_adapter( PIA *pi, char * scratch, int verbose )
{ char *mode_string[5] = {"4-bit","8-bit","EPP-8",
"EPP-16","EPP-32"};
printk("%s: dstr %s, DataStor EP2000 at 0x%x, ",
pi->device,DSTR_VERSION,pi->port);
printk("mode %d (%s), delay %d\n",pi->mode,
mode_string[pi->mode],pi->delay);
}
static void dstr_inc_use ( void )
{ MOD_INC_USE_COUNT;
}
static void dstr_dec_use ( void )
{ MOD_DEC_USE_COUNT;
}
struct pi_protocol dstr = {"dstr",0,5,2,1,1,
dstr_write_regr,
dstr_read_regr,
dstr_write_block,
dstr_read_block,
dstr_connect,
dstr_disconnect,
0,
0,
0,
dstr_log_adapter,
dstr_inc_use,
dstr_dec_use
};
#ifdef MODULE
int init_module(void)
{ return pi_register( &dstr ) - 1;
}
void cleanup_module(void)
{ pi_unregister( &dstr );
}
#endif
/* end of dstr.c */
/*
epat.c (c) 1997 Grant R. Guenther <grant@torque.net>
Under the terms of the GNU public license.
This is the low level protocol driver for the EPAT parallel
to IDE adapter from Shuttle Technologies. This adapter is
used in many popular parallel port disk products such as the
SyQuest EZ drives, the Avatar Shark and the Imation SuperDisk.
*/
#define EPAT_VERSION "1.0"
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <asm/io.h>
#include "paride.h"
#define j44(a,b) (((a>>4)&0x0f)+(b&0xf0))
#define j53(a,b) (((a>>3)&0x1f)+((b<<4)&0xe0))
/* cont = 0 IDE register file
cont = 1 IDE control registers
cont = 2 internal EPAT registers
*/
static int cont_map[3] = { 0x18, 0x10, 0 };
static void epat_write_regr( PIA *pi, int cont, int regr, int val)
{ int r;
r = regr + cont_map[cont];
switch (pi->mode) {
case 0:
case 1:
case 2: w0(0x60+r); w2(1); w0(val); w2(4);
break;
case 3:
case 4:
case 5: w3(0x40+r); w4(val);
break;
}
}
static int epat_read_regr( PIA *pi, int cont, int regr )
{ int a, b, r;
r = regr + cont_map[cont];
switch (pi->mode) {
case 0: w0(r); w2(1); w2(3);
a = r1(); w2(4); b = r1();
return j44(a,b);
case 1: w0(0x40+r); w2(1); w2(4);
a = r1(); b = r2(); w0(0xff);
return j53(a,b);
case 2: w0(0x20+r); w2(1); w2(0x25);
a = r0(); w2(4);
return a;
case 3:
case 4:
case 5: w3(r); w2(0x24); a = r4(); w2(4);
return a;
}
return -1; /* never gets here */
}
static void epat_read_block( PIA *pi, char * buf, int count )
{ int k, ph, a, b;
switch (pi->mode) {
case 0: w0(7); w2(1); w2(3); w0(0xff);
ph = 0;
for(k=0;k<count;k++) {
if (k == count-1) w0(0xfd);
w2(6+ph); a = r1();
if (a & 8) b = a;
else { w2(4+ph); b = r1(); }
buf[k] = j44(a,b);
ph = 1 - ph;
}
w0(0); w2(4);
break;
case 1: w0(0x47); w2(1); w2(5); w0(0xff);
ph = 0;
for(k=0;k<count;k++) {
if (k == count-1) w0(0xfd);
w2(4+ph);
a = r1(); b = r2();
buf[k] = j53(a,b);
ph = 1 - ph;
}
w0(0); w2(4);
break;
case 2: w0(0x27); w2(1); w2(0x25); w0(0);
ph = 0;
for(k=0;k<count-1;k++) {
w2(0x24+ph);
buf[k] = r0();
ph = 1 - ph;
}
w2(0x26); w2(0x27); buf[count-1] = r0();
w2(0x25); w2(4);
break;
case 3: w3(0x80); w2(0x24);
for(k=0;k<count-1;k++) buf[k] = r4();
w2(4); w3(0xa0); w2(0x24); buf[count-1] = r4();
w2(4);
break;
case 4: w3(0x80); w2(0x24);
for(k=0;k<(count/2)-1;k++) ((u16 *)buf)[k] = r4w();
buf[count-2] = r4();
w2(4); w3(0xa0); w2(0x24); buf[count-1] = r4();
w2(4);
break;
case 5: w3(0x80); w2(0x24);
for(k=0;k<(count/4)-1;k++) ((u32 *)buf)[k] = r4l();
for(k=count-4;k<count-1;k++) buf[k] = r4();
w2(4); w3(0xa0); w2(0x24); buf[count-1] = r4();
w2(4);
break;
}
}
static void epat_write_block( PIA *pi, char * buf, int count )
{ int ph, k;
switch (pi->mode) {
case 0:
case 1:
case 2: w0(0x67); w2(1); w2(5);
ph = 0;
for(k=0;k<count;k++) {
w0(buf[k]);
w2(4+ph);
ph = 1 - ph;
}
w2(7); w2(4);
break;
case 3: w3(0xc0);
for(k=0;k<count;k++) w4(buf[k]);
w2(4);
break;
case 4: w3(0xc0);
for(k=0;k<(count/2);k++) w4w(((u16 *)buf)[k]);
w2(4);
break;
case 5: w3(0xc0);
for(k=0;k<(count/4);k++) w4l(((u32 *)buf)[k]);
w2(4);
break;
}
}
/* these macros access the EPAT registers in native addressing */
#define WR(r,v) epat_write_regr(pi,2,r,v)
#define RR(r) (epat_read_regr(pi,2,r))
/* and these access the IDE task file */
#define WRi(r,v) epat_write_regr(pi,0,r,v)
#define RRi(r) (epat_read_regr(pi,0,r))
/* FIXME: the CCP stuff should be fixed to handle multiple EPATs on a chain */
#define CCP(x) w2(4);w0(0x22);w0(0xaa);w0(0x55);w0(0);w0(0xff);\
w0(0x87);w0(0x78);w0(x);w2(4);w2(5);w2(4);w0(0xff);
static void epat_connect ( PIA *pi )
{ pi->saved_r0 = r0();
pi->saved_r2 = r2();
CCP(0); CCP(0xe0);
w0(0); w2(1); w2(4);
if (pi->mode >= 3) {
w0(0); w2(1); w2(4); w2(0xc);
w0(0x40); w2(6); w2(7); w2(4); w2(0xc); w2(4);
}
WR(8,0x10); WR(0xc,0x14); WR(0xa,0x38); WR(0x12,0x10);
}
static void epat_disconnect ( PIA *pi )
{ CCP(0x30);
w0(pi->saved_r0);
w2(pi->saved_r2);
}
static int epat_test_proto( PIA *pi, char * scratch, int verbose )
{ int k, j, f, cc;
int e[2] = {0,0};
epat_connect(pi);
cc = RR(0xd);
epat_disconnect(pi);
epat_connect(pi);
for (j=0;j<2;j++) {
WRi(6,0xa0+j*0x10);
for (k=0;k<256;k++) {
WRi(2,k^0xaa);
WRi(3,k^0x55);
if (RRi(2) != (k^0xaa)) e[j]++;
}
}
epat_disconnect(pi);
f = 0;
epat_connect(pi);
WR(0x13,1); WR(0x13,0); WR(0xa,0x11);
epat_read_block(pi,scratch,512);
for (k=0;k<256;k++) {
if ((scratch[2*k] & 0xff) != k) f++;
if ((scratch[2*k+1] & 0xff) != (0xff-k)) f++;
}
epat_disconnect(pi);
if (verbose) {
printk("%s: epat: port 0x%x, mode %d, ccr %x, test=(%d,%d,%d)\n",
pi->device,pi->port,pi->mode,cc,e[0],e[1],f);
}
return (e[0] && e[1]) || f;
}
static void epat_log_adapter( PIA *pi, char * scratch, int verbose )
{ int ver;
char *mode_string[6] =
{"4-bit","5/3","8-bit","EPP-8","EPP-16","EPP-32"};
epat_connect(pi);
WR(0xa,0x38); /* read the version code */
ver = RR(0xb);
epat_disconnect(pi);
printk("%s: epat %s, Shuttle EPAT chip %x at 0x%x, ",
pi->device,EPAT_VERSION,ver,pi->port);
printk("mode %d (%s), delay %d\n",pi->mode,
mode_string[pi->mode],pi->delay);
}
static void epat_inc_use ( void )
{ MOD_INC_USE_COUNT;
}
static void epat_dec_use ( void )
{ MOD_DEC_USE_COUNT;
}
struct pi_protocol epat = {"epat",0,6,3,1,1,
epat_write_regr,
epat_read_regr,
epat_write_block,
epat_read_block,
epat_connect,
epat_disconnect,
0,
0,
epat_test_proto,
epat_log_adapter,
epat_inc_use,
epat_dec_use
};
#ifdef MODULE
int init_module(void)
{ return pi_register( &epat) - 1;
}
void cleanup_module(void)
{ pi_unregister( &epat);
}
#endif
/* end of epat.c */
/*
epia.c (c) 1997 Grant R. Guenther <grant@torque.net>
Under the terms of the GNU public license.
epia.c is a low-level protocol driver for Shuttle Technologies
EPIA parallel to IDE adapter chip. This device is now obsolete
and has been replaced with the EPAT chip, which is supported
by epat.c, however, some devices based on EPIA are still
available.
*/
#define EPIA_VERSION "1.0"
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <asm/io.h>
#include "paride.h"
/* mode codes: 0 nybble reads on port 1, 8-bit writes
1 5/3 reads on ports 1 & 2, 8-bit writes
2 8-bit reads and writes
3 8-bit EPP mode
4 16-bit EPP
5 32-bit EPP
*/
#define j44(a,b) (((a>>4)&0x0f)+(b&0xf0))
#define j53(a,b) (((a>>3)&0x1f)+((b<<4)&0xe0))
/* cont = 0 IDE register file
cont = 1 IDE control registers
*/
static int cont_map[2] = { 0, 0x80 };
static int epia_read_regr( PIA *pi, int cont, int regr )
{ int a, b, r;
regr += cont_map[cont];
switch (pi->mode) {
case 0: r = regr^0x39;
w0(r); w2(1); w2(3); w0(r);
a = r1(); w2(1); b = r1(); w2(4);
return j44(a,b);
case 1: r = regr^0x31;
w0(r); w2(1); w0(r&0x37);
w2(3); w2(5); w0(r|0xf0);
a = r1(); b = r2(); w2(4);
return j53(a,b);
case 2: r = regr^0x29;
w0(r); w2(1); w2(0X21); w2(0x23);
a = r0(); w2(4);
return a;
case 3:
case 4:
case 5: w3(regr); w2(0x24); a = r4(); w2(4);
return a;
}
return -1;
}
static void epia_write_regr( PIA *pi, int cont, int regr, int val)
{ int r;
regr += cont_map[cont];
switch (pi->mode) {
case 0:
case 1:
case 2: r = regr^0x19;
w0(r); w2(1); w0(val); w2(3); w2(4);
break;
case 3:
case 4:
case 5: r = regr^0x40;
w3(r); w4(val); w2(4);
break;
}
}
#define WR(r,v) epia_write_regr(pi,0,r,v)
#define RR(r) (epia_read_regr(pi,0,r))
/* The use of register 0x84 is entirely unclear - it seems to control
some EPP counters ... currently we know about 3 different block
sizes: the standard 512 byte reads and writes, 12 byte writes and
2048 byte reads (the last two being used in the CDrom drivers.
*/
static void epia_connect ( PIA *pi )
{ pi->saved_r0 = r0();
pi->saved_r2 = r2();
w2(4); w0(0xa0); w0(0x50); w0(0xc0); w0(0x30); w0(0xa0); w0(0);
w2(1); w2(4);
if (pi->mode >= 3) {
w0(0xa); w2(1); w2(4); w0(0x82); w2(4); w2(0xc); w2(4);
w2(0x24); w2(0x26); w2(4);
}
WR(0x86,8);
}
static void epia_disconnect ( PIA *pi )
{ WR(0x84,0x10);
w0(pi->saved_r0);
w2(1); w2(4);
w0(pi->saved_r0);
w2(pi->saved_r2);
}
static void epia_read_block( PIA *pi, char * buf, int count )
{ int k, ph, a, b;
switch (pi->mode) {
case 0: w0(0x81); w2(1); w2(3); w0(0xc1);
ph = 1;
for (k=0;k<count;k++) {
w2(2+ph); a = r1();
w2(4+ph); b = r1();
buf[k] = j44(a,b);
ph = 1 - ph;
}
w0(0); w2(4);
break;
case 1: w0(0x91); w2(1); w0(0x10); w2(3);
w0(0x51); w2(5); w0(0xd1);
ph = 1;
for (k=0;k<count;k++) {
w2(4+ph);
a = r1(); b = r2();
buf[k] = j53(a,b);
ph = 1 - ph;
}
w0(0); w2(4);
break;
case 2: w0(0x89); w2(1); w2(0x23); w2(0x21);
ph = 1;
for (k=0;k<count;k++) {
w2(0x24+ph);
buf[k] = r0();
ph = 1 - ph;
}
w2(6); w2(4);
break;
case 3: if (count > 512) WR(0x84,3);
w3(0); w2(0x24);
for (k=0;k<count;k++) buf[k] = r4();
w2(4); WR(0x84,0);
break;
case 4: if (count > 512) WR(0x84,3);
w3(0); w2(0x24);
for (k=0;k<count/2;k++) ((u16 *)buf)[k] = r4w();
w2(4); WR(0x84,0);
break;
case 5: if (count > 512) WR(0x84,3);
w3(0); w2(0x24);
for (k=0;k<count/4;k++) ((u32 *)buf)[k] = r4l();
w2(4); WR(0x84,0);
break;
}
}
static void epia_write_block( PIA *pi, char * buf, int count )
{ int ph, k, last, d;
switch (pi->mode) {
case 0:
case 1:
case 2: w0(0xa1); w2(1); w2(3); w2(1); w2(5);
ph = 0; last = 0x8000;
for (k=0;k<count;k++) {
d = buf[k];
if (d != last) { last = d; w0(d); }
w2(4+ph);
ph = 1 - ph;
}
w2(7); w2(4);
break;
case 3: if (count < 512) WR(0x84,1);
w3(0x40);
for (k=0;k<count;k++) w4(buf[k]);
if (count < 512) WR(0x84,0);
break;
case 4: if (count < 512) WR(0x84,1);
w3(0x40);
for (k=0;k<count/2;k++) w4w(((u16 *)buf)[k]);
if (count < 512) WR(0x84,0);
break;
case 5: if (count < 512) WR(0x84,1);
w3(0x40);
for (k=0;k<count/4;k++) w4l(((u32 *)buf)[k]);
if (count < 512) WR(0x84,0);
break;
}
}
static int epia_test_proto( PIA *pi, char * scratch, int verbose )
{ int j, k, f;
int e[2] = {0,0};
epia_connect(pi);
for (j=0;j<2;j++) {
WR(6,0xa0+j*0x10);
for (k=0;k<256;k++) {
WR(2,k^0xaa);
WR(3,k^0x55);
if (RR(2) != (k^0xaa)) e[j]++;
}
}
epia_disconnect(pi);
f = 0;
epia_connect(pi);
WR(0x84,8);
epia_read_block(pi,scratch,512);
for (k=0;k<256;k++) {
if ((scratch[2*k] & 0xff) != ((k+1) & 0xff)) f++;
if ((scratch[2*k+1] & 0xff) != ((-2-k) & 0xff)) f++;
}
WR(0x84,0);
epia_disconnect(pi);
if (verbose) {
printk("%s: epia: port 0x%x, mode %d, test=(%d,%d,%d)\n",
pi->device,pi->port,pi->mode,e[0],e[1],f);
}
return (e[0] && e[1]) || f;
}
static void epia_log_adapter( PIA *pi, char * scratch, int verbose )
{ char *mode_string[6] = {"4-bit","5/3","8-bit",
"EPP-8","EPP-16","EPP-32"};
printk("%s: epia %s, Shuttle EPIA at 0x%x, ",
pi->device,EPIA_VERSION,pi->port);
printk("mode %d (%s), delay %d\n",pi->mode,
mode_string[pi->mode],pi->delay);
}
static void epia_inc_use ( void )
{ MOD_INC_USE_COUNT;
}
static void epia_dec_use ( void )
{ MOD_DEC_USE_COUNT;
}
struct pi_protocol epia = {"epia",0,6,3,1,1,
epia_write_regr,
epia_read_regr,
epia_write_block,
epia_read_block,
epia_connect,
epia_disconnect,
0,
0,
epia_test_proto,
epia_log_adapter,
epia_inc_use,
epia_dec_use
};
#ifdef MODULE
int init_module(void)
{ return pi_register( &epia ) - 1;
}
void cleanup_module(void)
{ pi_unregister( &epia );
}
#endif
/* end of epia.c */
/*
frpw.c (c) 1997 Grant R. Guenther <grant@torque.net>
Under the terms of the GNU public license
frpw.c is a low-level protocol driver for the Freecom "Power"
parallel port IDE adapter.
*/
#define FRPW_VERSION "1.0"
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <asm/io.h>
#include "paride.h"
#define cec4 w2(0xc);w2(0xe);w2(0xe);w2(0xc);w2(4);w2(4);w2(4);
#define j44(l,h) (((l>>4)&0x0f)|(h&0xf0))
/* cont = 0 - access the IDE register file
cont = 1 - access the IDE command set
*/
static int cont_map[2] = { 0x08, 0x10 };
static int frpw_read_regr( PIA *pi, int cont, int regr )
{ int h,l,r;
r = regr + cont_map[cont];
w2(4);
w0(r); cec4;
w2(6); l = r1();
w2(4); h = r1();
w2(4);
return j44(l,h);
}
static void frpw_write_regr( PIA *pi, int cont, int regr, int val)
{ int r;
r = regr + cont_map[cont];
w2(4); w0(r); cec4;
w0(val);
w2(5);w2(7);w2(5);w2(4);
}
static void frpw_read_block_int( PIA *pi, char * buf, int count, int regr )
{ int h, l, k, ph;
switch(pi->mode) {
case 0: w2(4); w0(regr); cec4;
for (k=0;k<count;k++) {
w2(6); l = r1();
w2(4); h = r1();
buf[k] = j44(l,h);
}
w2(4);
break;
case 1: ph = 2;
w2(4); w0(regr + 0xc0); cec4;
w0(0xff);
for (k=0;k<count;k++) {
w2(0xa4 + ph);
buf[k] = r0();
ph = 2 - ph;
}
w2(0xac); w2(0xa4); w2(4);
break;
case 2: w2(4); w0(regr + 0x80); cec4;
for (k=0;k<count;k++) buf[k] = r4();
w2(0xac); w2(0xa4);
w2(4);
break;
case 3: w2(4); w0(regr + 0x80); cec4;
for (k=0;k<count-2;k++) buf[k] = r4();
w2(0xac); w2(0xa4);
buf[count-2] = r4();
buf[count-1] = r4();
w2(4);
break;
}
}
static void frpw_read_block( PIA *pi, char * buf, int count)
{ frpw_read_block_int(pi,buf,count,0x08);
}
static void frpw_write_block( PIA *pi, char * buf, int count )
{ int k;
switch(pi->mode) {
case 0:
case 1:
case 2: w2(4); w0(8); cec4; w2(5);
for (k=0;k<count;k++) {
w0(buf[k]);
w2(7);w2(5);
}
w2(4);
break;
case 3: w2(4); w0(0xc8); cec4; w2(5);
for (k=0;k<count;k++) w4(buf[k]);
w2(4);
break;
}
}
static void frpw_connect ( PIA *pi )
{ pi->saved_r0 = r0();
pi->saved_r2 = r2();
w2(4);
}
static void frpw_disconnect ( PIA *pi )
{ w2(4); w0(0x20); cec4;
w0(pi->saved_r0);
w2(pi->saved_r2);
}
/* Stub logic to see if PNP string is available - used to distinguish
between the Xilinx and ASIC implementations of the Freecom adapter.
*/
static int frpw_test_pnp ( PIA *pi )
{ int olddelay, a, b;
olddelay = pi->delay;
pi->delay = 10;
pi->saved_r0 = r0();
pi->saved_r2 = r2();
w2(4); w0(4); w2(6); w2(7);
a = r1() & 0xff; w2(4); b = r1() & 0xff;
w2(0xc); w2(0xe); w2(4);
pi->delay = olddelay;
w0(pi->saved_r0);
w2(pi->saved_r2);
return ((~a&0x40) && (b&0x40));
}
/* We use pi->private to record the chip type:
0 = untested, 2 = Xilinx, 3 = ASIC
*/
static int frpw_test_proto( PIA *pi, char * scratch, int verbose )
{ int k, r;
if (!pi->private) pi->private = frpw_test_pnp(pi) + 2;
if ((pi->private == 2) && (pi->mode > 2)) {
if (verbose)
printk("%s: frpw: Xilinx does not support mode %d\n",
pi->device, pi->mode);
return 1;
}
if ((pi->private == 3) && (pi->mode == 2)) {
if (verbose)
printk("%s: frpw: ASIC does not support mode 2\n",
pi->device);
return 1;
}
frpw_connect(pi);
frpw_read_block_int(pi,scratch,512,0x10);
r = 0;
for (k=0;k<128;k++) if (scratch[k] != k) r++;
frpw_disconnect(pi);
if (verbose) {
printk("%s: frpw: port 0x%x, mode %d, test=%d\n",
pi->device,pi->port,pi->mode,r);
}
return r;
}
static void frpw_log_adapter( PIA *pi, char * scratch, int verbose )
{ char *mode_string[4] = {"4-bit","8-bit","EPP-X","EPP-A"};
printk("%s: frpw %s, Freecom (%s) adapter at 0x%x, ", pi->device,
FRPW_VERSION,(pi->private == 2)?"Xilinx":"ASIC",pi->port);
printk("mode %d (%s), delay %d\n",pi->mode,
mode_string[pi->mode],pi->delay);
}
static void frpw_inc_use ( void )
{ MOD_INC_USE_COUNT;
}
static void frpw_dec_use ( void )
{ MOD_DEC_USE_COUNT;
}
struct pi_protocol frpw = {"frpw",0,4,2,2,1,
frpw_write_regr,
frpw_read_regr,
frpw_write_block,
frpw_read_block,
frpw_connect,
frpw_disconnect,
0,
0,
frpw_test_proto,
frpw_log_adapter,
frpw_inc_use,
frpw_dec_use
};
#ifdef MODULE
int init_module(void)
{ return pi_register( &frpw ) - 1;
}
void cleanup_module(void)
{ pi_unregister( &frpw );
}
#endif
/* end of frpw.c */
/*
kbic.c (c) 1997 Grant R. Guenther <grant@torque.net>
Under the terms of the GNU public license.
This is a low-level driver for the KBIC-951A and KBIC-971A
parallel to IDE adapter chips from KingByte Information Systems.
The chips are almost identical, however, the wakeup code
required for the 971A interferes with the correct operation of
the 951A, so this driver registers itself twice, once for
each chip.
*/
#define KBIC_VERSION "1.0"
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <asm/io.h>
#include "paride.h"
#define r12w() (delay_p,inw(pi->port+1)&0xffff)
#define j44(a,b) ((((a>>4)&0x0f)|(b&0xf0))^0x88)
#define j53(w) (((w>>3)&0x1f)|((w>>4)&0xe0))
/* cont = 0 - access the IDE register file
cont = 1 - access the IDE command set
*/
static int cont_map[2] = { 0x80, 0x40 };
static int kbic_read_regr( PIA *pi, int cont, int regr )
{ int a, b, s;
s = cont_map[cont];
switch (pi->mode) {
case 0: w0(regr|0x18|s); w2(4); w2(6); w2(4); w2(1); w0(8);
a = r1(); w0(0x28); b = r1(); w2(4);
return j44(a,b);
case 1: w0(regr|0x38|s); w2(4); w2(6); w2(4); w2(5); w0(8);
a = r12w(); w2(4);
return j53(a);
case 2: w0(regr|0x08|s); w2(4); w2(6); w2(4); w2(0xa5); w2(0xa1);
a = r0(); w2(4);
return a;
case 3:
case 4:
case 5: w0(0x20|s); w2(4); w2(6); w2(4); w3(regr);
a = r4(); b = r4(); w2(4); w2(0); w2(4);
return a;
}
return -1;
}
static void kbic_write_regr( PIA *pi, int cont, int regr, int val)
{ int s;
s = cont_map[cont];
switch (pi->mode) {
case 0:
case 1:
case 2: w0(regr|0x10|s); w2(4); w2(6); w2(4);
w0(val); w2(5); w2(4);
break;
case 3:
case 4:
case 5: w0(0x20|s); w2(4); w2(6); w2(4); w3(regr);
w4(val); w4(val);
w2(4); w2(0); w2(4);
break;
}
}
static void k951_connect ( PIA *pi )
{ pi->saved_r0 = r0();
pi->saved_r2 = r2();
w2(4);
}
static void k951_disconnect ( PIA *pi )
{ w0(pi->saved_r0);
w2(pi->saved_r2);
}
#define CCP(x) w2(0xc4);w0(0xaa);w0(0x55);w0(0);w0(0xff);w0(0x87);\
w0(0x78);w0(x);w2(0xc5);w2(0xc4);w0(0xff);
static void k971_connect ( PIA *pi )
{ pi->saved_r0 = r0();
pi->saved_r2 = r2();
CCP(0x20);
w2(4);
}
static void k971_disconnect ( PIA *pi )
{ CCP(0x30);
w0(pi->saved_r0);
w2(pi->saved_r2);
}
/* counts must be congruent to 0 MOD 4, but all known applications
have this property.
*/
static void kbic_read_block( PIA *pi, char * buf, int count )
{ int k, a, b;
switch (pi->mode) {
case 0: w0(0x98); w2(4); w2(6); w2(4);
for (k=0;k<count/2;k++) {
w2(1); w0(8); a = r1();
w0(0x28); b = r1();
buf[2*k] = j44(a,b);
w2(5); b = r1();
w0(8); a = r1();
buf[2*k+1] = j44(a,b);
w2(4);
}
break;
case 1: w0(0xb8); w2(4); w2(6); w2(4);
for (k=0;k<count/4;k++) {
w0(0xb8);
w2(4); w2(5);
w0(8); buf[4*k] = j53(r12w());
w0(0xb8); buf[4*k+1] = j53(r12w());
w2(4); w2(5);
buf[4*k+3] = j53(r12w());
w0(8); buf[4*k+2] = j53(r12w());
}
w2(4);
break;
case 2: w0(0x88); w2(4); w2(6); w2(4);
for (k=0;k<count/2;k++) {
w2(0xa0); w2(0xa1); buf[2*k] = r0();
w2(0xa5); buf[2*k+1] = r0();
}
w2(4);
break;
case 3: w0(0xa0); w2(4); w2(6); w2(4); w3(0);
for (k=0;k<count;k++) buf[k] = r4();
w2(4); w2(0); w2(4);
break;
case 4: w0(0xa0); w2(4); w2(6); w2(4); w3(0);
for (k=0;k<count/2;k++) ((u16 *)buf)[k] = r4w();
w2(4); w2(0); w2(4);
break;
case 5: w0(0xa0); w2(4); w2(6); w2(4); w3(0);
for (k=0;k<count/4;k++) ((u32 *)buf)[k] = r4l();
w2(4); w2(0); w2(4);
break;
}
}
static void kbic_write_block( PIA *pi, char * buf, int count )
{ int k;
switch (pi->mode) {
case 0:
case 1:
case 2: w0(0x90); w2(4); w2(6); w2(4);
for(k=0;k<count/2;k++) {
w0(buf[2*k+1]); w2(0); w2(4);
w0(buf[2*k]); w2(5); w2(4);
}
break;
case 3: w0(0xa0); w2(4); w2(6); w2(4); w3(0);
for(k=0;k<count/2;k++) {
w4(buf[2*k+1]);
w4(buf[2*k]);
}
w2(4); w2(0); w2(4);
break;
case 4: w0(0xa0); w2(4); w2(6); w2(4); w3(0);
for(k=0;k<count/2;k++) w4w(pi_swab16(buf,k));
w2(4); w2(0); w2(4);
break;
case 5: w0(0xa0); w2(4); w2(6); w2(4); w3(0);
for(k=0;k<count/4;k++) w4l(pi_swab32(buf,k));
w2(4); w2(0); w2(4);
break;
}
}
static void kbic_log_adapter( PIA *pi, char * scratch,
int verbose, char * chip )
{ char *mode_string[6] = {"4-bit","5/3","8-bit",
"EPP-8","EPP_16","EPP-32"};
printk("%s: kbic %s, KingByte %s at 0x%x, ",
pi->device,KBIC_VERSION,chip,pi->port);
printk("mode %d (%s), delay %d\n",pi->mode,
mode_string[pi->mode],pi->delay);
}
static void k951_log_adapter( PIA *pi, char * scratch, int verbose )
{ kbic_log_adapter(pi,scratch,verbose,"KBIC-951A");
}
static void k971_log_adapter( PIA *pi, char * scratch, int verbose )
{ kbic_log_adapter(pi,scratch,verbose,"KBIC-971A");
}
static void kbic_inc_use ( void )
{ MOD_INC_USE_COUNT;
}
static void kbic_dec_use ( void )
{ MOD_DEC_USE_COUNT;
}
struct pi_protocol k951 = {"k951",0,6,3,1,1,
kbic_write_regr,
kbic_read_regr,
kbic_write_block,
kbic_read_block,
k951_connect,
k951_disconnect,
0,
0,
0,
k951_log_adapter,
kbic_inc_use,
kbic_dec_use
};
struct pi_protocol k971 = {"k971",0,6,3,1,1,
kbic_write_regr,
kbic_read_regr,
kbic_write_block,
kbic_read_block,
k971_connect,
k971_disconnect,
0,
0,
0,
k971_log_adapter,
kbic_inc_use,
kbic_dec_use
};
#ifdef MODULE
int init_module(void)
{ int s5,s7;
s5 = pi_register(&k951);
s7 = pi_register(&k971);
return (s5 || s7) - 1;
}
void cleanup_module(void)
{ pi_unregister( &k951 );
pi_unregister( &k971 );
}
#endif
/* end of kbic.c */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -220,10 +220,10 @@ __initfunc(void ide_init_trm290 (ide_hwif_t *hwif))
&& !pcibios_read_config_dword(hwif->pci_bus, hwif->pci_fn, 0x20, &cfgbase) && cfgbase)
{
hwif->config_data = cfgbase & ~1;
printk("TRM290: chip config base at 0x%04x\n", hwif->config_data);
printk("TRM290: chip config base at 0x%04lx\n", hwif->config_data);
} else {
hwif->config_data = 0x3df4;
printk("TRM290: using default config base at 0x%04x\n", hwif->config_data);
hwif->config_data = 0x3df0;
printk("TRM290: using default config base at 0x%04lx\n", hwif->config_data);
}
save_flags(flags);
......@@ -241,7 +241,7 @@ __initfunc(void ide_init_trm290 (ide_hwif_t *hwif))
hwif->irq = hwif->channel ? 15 : 14; /* legacy mode */
else if (!hwif->irq && hwif->mate && hwif->mate->irq)
hwif->irq = hwif->mate->irq; /* sharing IRQ with mate */
ide_setup_dma(hwif, (hwif->channel ? hwif->config_data ^ 0x0080 : hwif->config_data) + 4, 2);
ide_setup_dma(hwif, (hwif->config_data + 4) ^ (hwif->channel ? 0x0080 : 0x0000), 2);
hwif->dmaproc = &trm290_dmaproc;
hwif->selectproc = &trm290_selectproc;
hwif->no_autodma = 1; /* play it safe for now */
......
......@@ -13,7 +13,6 @@ if [ "$CONFIG_SBPCD" = "y" ]; then
fi
fi
fi
tristate 'MicroSolutions backpack CDROM support' CONFIG_BPCD
tristate 'Mitsumi (standard) [no XA/Multisession] CDROM support' CONFIG_MCD
tristate 'Mitsumi [XA/MultiSession] CDROM support' CONFIG_MCDX
tristate 'Optics Storage DOLPHIN 8000AT CDROM support' CONFIG_OPTCD
......
......@@ -112,14 +112,6 @@ else
endif
endif #CONFIG_SJCD
ifeq ($(CONFIG_BPCD),y)
L_OBJS += bpcd.o
else
ifeq ($(CONFIG_BPCD),m)
M_OBJS += bpcd.o
endif
endif #CONFIG_BPCD
ifeq ($(CONFIG_ISP16_CDI),y)
L_OBJS += isp16.o
else
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -110,7 +110,7 @@ if [ "$CONFIG_ALPHA_BOOK1" = "y" ]; then
fi
tristate 'Video For Linux' CONFIG_VIDEO_DEV
dep_tristate 'BT848 Video For Linux' CONFIG_VIDEO_BT848 $CONFIG_VIDEO_DEV
#dep_tristate 'Quickcam BW Video For Linux' CONFIG_VIDEO_BWQCAM $CONFIG_VIDEO_DEV
dep_tristate 'Quickcam BW Video For Linux' CONFIG_VIDEO_BWQCAM $CONFIG_VIDEO_DEV
dep_tristate 'Mediavision Pro Movie Studio Video For Linux' CONFIG_VIDEO_PMS $CONFIG_VIDEO_DEV
tristate '/dev/nvram support' CONFIG_NVRAM
tristate 'PC joystick support' CONFIG_JOYSTICK
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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