Commit 9d1ec5d7 authored by Linus Torvalds's avatar Linus Torvalds

- Alan Cox: synch. PA-RISC arch and bitops cleanups

- Maciej Rozycki: even more proper apic setup order.
- Andrew Morton: exec_usermodehelper fixes
- Adam Richter, Kai Germaschewski, Linus: PCI irq routing.
- revert A20 code changes. We really need to use the keyboard
  controller if one exists.
- Johannes Erdfelt: USB updates
- Ralf Baechle: MIPS memmove() fix.
parent 286d075e
...@@ -341,6 +341,7 @@ D: Texas Instruments PCILynx IEEE 1394 driver ...@@ -341,6 +341,7 @@ D: Texas Instruments PCILynx IEEE 1394 driver
N: Al Borchers N: Al Borchers
E: alborchers@steinerpoint.com E: alborchers@steinerpoint.com
D: Author/maintainer of Digi AccelePort USB driver D: Author/maintainer of Digi AccelePort USB driver
D: work on usbserial and keyspan_pda drivers
S: 4912 Zenith Ave. S. S: 4912 Zenith Ave. S.
S: Minneapolis, MN 55410 S: Minneapolis, MN 55410
S: USA S: USA
...@@ -410,6 +411,10 @@ N: Zach Brown ...@@ -410,6 +411,10 @@ N: Zach Brown
E: zab@zabbo.net E: zab@zabbo.net
D: maestro pci sound D: maestro pci sound
N: Gary Brubaker
E: xavyer@ix.netcom.com
D: USB Serial Empeg Empeg-car Mark I/II Driver
N: Ray Burr N: Ray Burr
E: ryb@nightmare.com E: ryb@nightmare.com
D: Original author of Amiga FFS filesystem D: Original author of Amiga FFS filesystem
......
...@@ -10372,6 +10372,9 @@ CONFIG_USB_SERIAL_DIGI_ACCELEPORT ...@@ -10372,6 +10372,9 @@ CONFIG_USB_SERIAL_DIGI_ACCELEPORT
parallel port on the USB 2 appears as a third serial port on Linux. parallel port on the USB 2 appears as a third serial port on Linux.
The Digi Acceleport USB 8 is not yet supported by this driver. The Digi Acceleport USB 8 is not yet supported by this driver.
This driver works under SMP with the usb-uhci driver. It does not
work under SMP with the uhci driver.
This code is also available as a module ( = code which can be This code is also available as a module ( = code which can be
inserted in and removed from the running kernel whenever you want). inserted in and removed from the running kernel whenever you want).
The module will be called digi_acceleport.o. If you want to compile The module will be called digi_acceleport.o. If you want to compile
...@@ -10380,7 +10383,9 @@ CONFIG_USB_SERIAL_DIGI_ACCELEPORT ...@@ -10380,7 +10383,9 @@ CONFIG_USB_SERIAL_DIGI_ACCELEPORT
USB Empeg empeg-car Mark I/II Driver USB Empeg empeg-car Mark I/II Driver
CONFIG_USB_SERIAL_EMPEG CONFIG_USB_SERIAL_EMPEG
Say Y here if you want to connect to your Empeg empeg-car Mark I/II Say Y here if you want to connect to your Empeg empeg-car Mark I/II
mp3 player via USB. mp3 player via USB. The driver uses a single ttyUSB{0,1,2,...}
device node. See Documentation/usb/usb-serial.txt for more
tidbits of information.
This code is also available as a module ( = code which can be This code is also available as a module ( = code which can be
inserted in and removed from the running kernel whenever you want). inserted in and removed from the running kernel whenever you want).
......
00-INDEX
- this file.
IODC.txt
- Documentation IODC
debugging
- some debugging hints for real-mode code
mm
- Documentation on parisc mm status
registers
- current/planned usage of registers
Some notes on IODC, its general brokenness, and how to work around it.
Short Version
IODC is HP's pre-PCI standard for device identification (a la PCI vendor,
device IDs), detection, configuration, initialization and so on.
It also can provide firmware function to do the actual IO, which are slow,
not really defined for runtime usage and generally not desirable. (There
are other firmware standards, such as STI, to do real IO).
Usually, there are two parts to IODC. The actual ROMs, which are laid out,
detected aso in a bus-specific manner (IO_DC_ADDRESS / IO_DC_DATA on
GSC/Runway, PCI spec - compliant ROMs for PCI, God-only-knows how on EISA),
and the slightly cooked data read by PDC_IODC.
The ROM layout is generally icky (only one byte out of every 4-byte-word
might be valid, and many devices don't implement required options), so
using PDC_IODC is highly recommended. (In fact, you should use the device
lists set up by the kernel proper instead of calling PDC_IODC yourself).
Now, let's have a look at what the cooked ROM looks like (see iodc.pdf for
the details, this is the simplified version).
Basically, the first 8 bytes of IODC contain two 32-bit ids called HVERSION
and SVERSION. Those are further split up into bit fields, and
unfortunately just ignoring this split up isn't an option.
SVERSION consists of a 4-bit revision field, a 20-bit model field and a
8-bit opt field. Now, forget the revision and opt fields exist. Basically,
the model field is equivalent to a PCI device id (there is no vendor id.
this is proprietary hardware we're talking about). That is, all your
driver cares for, in 90 % of the cases, is to find all devices that match
the model field.
The rev field is - you guessed it - roughly equivalent to the revision
byte for PCI, with the exception that higher revisions should be strict
supersets of lower revisions.
The last byte of HVERSION, "type", and the last byte of SVERSION, "opt",
belong together; type gives a very rough indication of what the device
is supposed to do, and opt contains some type-specific information. (For
example, the "bus converter" (ie bus bridge) type encodes the kind of
bus behind the bridge in the opt field.
The rest of HVERSION contains, in most cases, a number identifying the
machine the chip was used in, or a revision indicator that just fixed
bugs and didn't add any features (or was done in a shrinked process or
whatever).
So, here's the interface you actually should use to find your devices:
/* Find a device, matching the model field of sversion only (from=NULL
* for the first call */
struct iodc_dev *iodc_find_device(u32 sversion, struct iodc_dev *from);
Here's a function you should use if you have special requirements, such
as finding devices by type rather than by model. Generally, if you're
using this, you should be me).
/* Find a device, masking out bits as specified */
struct iodc_dev *iodc_find_device_mask(u32 hversion, u32 sversion,
u32 hversion_mask, u32 sversion_mask, struct iodc_dev *from);
Philipp Rumpf <prumpf@tux.org>
okay, here are some hints for debugging the lower-level parts of
linux/parisc.
1. Absolute addresses
A lot of the assembly code currently runs in real mode, which means
absolute addresses are used instead of virtual addresses as in the
rest of the kernel. To translate an absolute address to a virtual
address you can lookup in System.map, add __PAGE_OFFSET (0xc0000000
currently).
2. HPMCs
When real-mode code tries to access non-existent memory, you'll get
an HPMC instead of a kernel oops. To debug an HPMC, try to find
the System Responder/Requestor addresses. The System Requestor
address should match (one of the) processor HPAs (high addresses in
the I/O range); the System Responder address is the address real-mode
code tried to access.
Typical values for the System Responder address are addresses larger
than __PAGE_OFFSET (0xc0000000) which mean a virtual address didn't
get translated to a physical address before real-mode code tried to
access it.
3. Q bit fun
Certain, very critical code has to clear the Q bit in the PSW. What
happens when the Q bit is cleared is the CPU does not update the
registers interruption handlers read to find out where the machine
was interrupted - so if you get an interruption between the instruction
that clears the Q bit and the RFI that sets it again you don't know
where exactly it happened. If you're lucky the IAOQ will point to the
instrucion that cleared the Q bit, if you're not it points anywhere
at all. Usually Q bit problems will show themselves in unexplainable
system hangs or running off the end of physical memory.
The current state of Linux/PA-RISC mm is BROKEN.
Someone needs to sit down and thoroughly rewrite all the cache flushing
macro definitions. Here are some of the problems, followed by what I
think needs to be done about them.
(1) We're using fdce / fice everywhere. This has to stop (except in
the routines which flush the entire cache). The right instructions to
be using are fdc/fic.
(2) fdc/fic will throw exceptions if the address they reference isn't
mapped. Therefore we need to check the page is mapped before flushing
(we're guaranteed not to have the page dirty if we don't have a software
mapping for it any longer, right?)
(3) the flush macros are right now tunnelled down to one routine to flush
the data cache and one routine to flush the insn cache. this is wrong.
we should take hints from how we're called and optimise our routines
accordingly.
(4) fdc/fic actually take space register arguments. fic takes an 3-bit sr
argument and fdc takes a 2-bit sr argument. right now, there's a lot of
pissing about with %sr1 and all the macros use %sr1. This is crazy. We
normally _know_ what's being referred to, and it's the current task. So
if we want to flush that, just use %sr3. If it happens to be kernel,
use %sr0 for fdc and %sr4 for fic.
(5) we need to write flush_kernel_dcache_range and use it on kernel
addresses. all the macros are defined to work on the _current task's_
virtual address space.
Register Usage for Linux/PA-RISC
[ an asterisk is used for planned usage which is currently unimplemented ]
General Registers as specified by ABI
FPU Registers must not be used in kernel mode
Control Registers
CR 0 (Recovery Counter) used for ptrace
CR 1-CR 7(undefined) unused
CR 8 (Protection ID) per-process value*
CR 9, 12, 13 (PIDS) unused
CR10 (CCR) lazy FPU saving*
CR11 as specified by ABI
CR14 (interruption vector) initialized to fault_vector
CR15 (EIEM) initialized to all ones*
CR16 (Interval Timer) timer interrupt
CR17-CR22 interruption parameters
CR23 (EIRR) read for pending interrupts
CR24 (TR 0) Kernel Space Page Directory Pointer
CR25 (TR 1) User Space Page Directory Pointer
CR26 (TR 2)
CR27 (TR 3)
CR28 (TR 4) used by interruption handlers
CR29 (TR 5) used by interruption handlers
CR30 (TR 6) current / 0
CR31 (TR 7) used by interruption handlers
Space Registers (kernel mode)
SR0 temporary space register
SR4-SR7 set to 0
SR1 temporary space register
SR2 unused
SR3 used for userspace accesses (current process)*
Space Registers (user mode)
SR0 temporary space register
SR1 temporary space register
SR2 holds space of linux gateway page
SR3 holds user address space value while in kernel
SR4-SR7 Defines short address space for user/kernel
Processor Status Word
W (64-bit addresses) 0
E (Little-endian) 0
S (Secure Interval Timer) 0
T (Taken Branch Trap) 0
H (Higher-privilege trap) 0
L (Lower-privilege trap) 0
N (Nullify next instruction) used by C code
X (Data memory break disable) 0
B (Taken Branch) used by C code
C (code address translation) 1, 0 while executing real-mode code
V (divide step correction) used by C code
M (HPMC mask) 0, 1 while executing HPMC handler*
C/B (carry/borrow bits) used by C code
O (ordered references) 1*
F (performance monitor) 0
R (Recovery Counter trap) 0
Q (collect interruption state) 1 (0 in code directly preceding an rfi)
P (Protection Identifiers) 1*
D (Data address translation) 1, 0 while executing real-mode code
I (external interrupt mask) used by cli()/sti() macros
"Invisible" Registers
PSW default W value 0
PSW default E value 0
Shadow Registers used by interruption handler code
TOC enable bit 1
=========================================================================
Info from John Marvin:
From: "John Marvin" <jsm@udlkern.fc.hp.com>
To: randolf@tausq.org
Subject: Re: parisc asm questions
[...]
For the general registers:
r1,r2,r19-r26,r28,r29 & r31 can be used without saving them first. And of
course, you need to save them if you care about them, before calling
another procedure. Some of the above registers do have special meanings
that you should be aware of:
r1: The addil instruction is hardwired to place its result in r1,
so if you use that instruction be aware of that.
r2: This is the return pointer. In general you don't want to
use this, since you need the pointer to get back to your
caller. However, it is grouped with this set of registers
since the caller can't rely on the value being the same
when you return, i.e. you can copy r2 to another register
and return through that register after trashing r2, and
that should not cause a problem for the calling routine.
r19-r22: these are generally regarded as temporary registers.
Note that in 64 bit they are arg7-arg4.
r23-r26: these are arg3-arg0, i.e. you can use them if you
don't care about the values that were passed in anymore.
r28,r29: are ret0 and ret1. They are what you pass return values
in. r28 is the primary return. I'm not sure I remember
under what circumstances stuff is returned in r29 (millicode
perhaps).
r31: the ble instruction puts the return pointer in here.
r3-r18,r27,r30 need to be saved and restored. r3-r18 are just
general purpose registers. r27 is the data pointer, and is
used to make references to global variables easier. r30 is
the stack pointer.
John
Revised: 2000-Dec-05.
1. Specification of the API 1. Specification of the API
1.1. Basic concept or 'What is an URB?' 1.1. Basic concept or 'What is an URB?'
...@@ -8,16 +10,16 @@ called USB Request Block, or URB for short. ...@@ -8,16 +10,16 @@ called USB Request Block, or URB for short.
- An URB consists of all relevant information to execute any USB transaction - An URB consists of all relevant information to execute any USB transaction
and deliver the data and status back. and deliver the data and status back.
- Execution of an URB is an inherently asynchronous operation, i.e. the - Execution of an URB is inherently an asynchronous operation, i.e. the
submit_urb(urb) call returns immediately after it has successfully queued usb_submit_urb(urb) call returns immediately after it has successfully queued
the requested action. the requested action.
- Ongoing transfers for one URB (e.g. ISO) can simply be canceled with - Ongoing transfers for one URB (e.g. ISO) can simply be canceled with
unlink_urb(urb) at any time. usb_unlink_urb(urb) at any time.
- Each URB has a completion handler, which is called after the action - Each URB has a completion handler, which is called after the action
has been successfully completed or canceled (INT transfers behave a bit has been successfully completed or canceled (INT transfers behave a bit
different, see below). The URB also contains a context-pointer for free differently, see below). The URB also contains a context-pointer for free
usage and information passing to the completion handler. usage and information passing to the completion handler.
- URBs can be linked. After completing one URB, the next one can be - URBs can be linked. After completing one URB, the next one can be
...@@ -31,6 +33,8 @@ URB-machinery. ...@@ -31,6 +33,8 @@ URB-machinery.
typedef struct urb typedef struct urb
{ {
spinlock_t lock; // lock for the URB
// ignore, for host controller/URB machine internal use // ignore, for host controller/URB machine internal use
void *hcpriv; // private data for host controller void *hcpriv; // private data for host controller
struct list_head urb_list; // list pointer to all active urbs struct list_head urb_list; // list pointer to all active urbs
...@@ -39,12 +43,12 @@ typedef struct urb ...@@ -39,12 +43,12 @@ typedef struct urb
struct urb* next; // pointer to next URB struct urb* next; // pointer to next URB
struct usb_device *dev; // pointer to associated USB device struct usb_device *dev; // pointer to associated USB device
// pipe is assembled by the various well known pipe-macros in usb.h // pipe is assembled by the various well-known pipe macros in usb.h
unsigned int pipe; // pipe information unsigned int pipe; // pipe information
// status after each completion // status after each completion
int status; // returned status int status; // returned status
unsigned int transfer_flags; // ASAP, SP_OK, etc. unsigned int transfer_flags; // ASAP, DISABLE_SPD, etc.
// for data stage (CTRL), BULK, INT and ISO // for data stage (CTRL), BULK, INT and ISO
void *transfer_buffer; // associated data buffer void *transfer_buffer; // associated data buffer
...@@ -55,7 +59,7 @@ typedef struct urb ...@@ -55,7 +59,7 @@ typedef struct urb
// setup stage for CTRL (always 8 bytes!) // setup stage for CTRL (always 8 bytes!)
unsigned char* setup_packet; // setup packet (control only) unsigned char* setup_packet; // setup packet (control only)
// with ASAP, start_frame is set to the determined frame // with ASAP, start_frame is set to the determined frame
int start_frame; // start frame (iso/irq) int start_frame; // start frame (iso/irq)
int number_of_packets; // # of packets (iso/int) int number_of_packets; // # of packets (iso/int)
...@@ -66,7 +70,7 @@ typedef struct urb ...@@ -66,7 +70,7 @@ typedef struct urb
usb_complete_t complete; // pointer to completion routine usb_complete_t complete; // pointer to completion routine
// //
// specification of the requested data offsets and length for ISO // specification of the requested data offsets and length for ISO
iso_packet_descriptor_t iso_frame_desc[0]; iso_packet_descriptor_t iso_frame_desc[0];
} urb_t, *purb_t; } urb_t, *purb_t;
...@@ -74,7 +78,7 @@ typedef struct urb ...@@ -74,7 +78,7 @@ typedef struct urb
URBs are allocated with the following call URBs are allocated with the following call
purb_t alloc_urb(int isoframes) purb_t usb_alloc_urb(int isoframes)
Return value is a pointer to the allocated URB, 0 if allocation failed. Return value is a pointer to the allocated URB, 0 if allocation failed.
The parameter isoframes specifies the number of isochronous transfer frames The parameter isoframes specifies the number of isochronous transfer frames
...@@ -82,7 +86,7 @@ you want to schedule. For CTRL/BULK/INT, use 0. ...@@ -82,7 +86,7 @@ you want to schedule. For CTRL/BULK/INT, use 0.
To free an URB, use To free an URB, use
void free_urb(purb_t purb) void usb_free_urb(purb_t purb)
This call also may free internal (host controller specific) memory in the This call also may free internal (host controller specific) memory in the
future. future.
...@@ -91,12 +95,13 @@ future. ...@@ -91,12 +95,13 @@ future.
1.4. What has to be filled in? 1.4. What has to be filled in?
Depending on the type of transaction, there are some macros Depending on the type of transaction, there are some macros
(FILL_CONTROL_URB, FILL_BULK_URB, and FILL_INT_URB, defined in uhci.h) (FILL_CONTROL_URB, FILL_CONTROL_URB_TO, FILL_BULK_URB,
FILL_BULK_URB_TO, and FILL_INT_URB, defined in usb.h)
that simplify the URB creation. In general, all macros need the usb that simplify the URB creation. In general, all macros need the usb
device pointer, the pipe (usual format), the transfer buffer, the device pointer, the pipe (usual format from usb.h), the transfer buffer,
desired transfer length, the completion handler, and its context. the desired transfer length, the completion handler, and its context.
Take a look at the uhci_control_msg-function that convert the old API Take a look at the usb_control_msg function that converts the old API
into an URB. into the URB API.
Flags: Flags:
For ISO there are two startup behaviors: Specified start_frame or ASAP. For ISO there are two startup behaviors: Specified start_frame or ASAP.
...@@ -114,7 +119,7 @@ re-submission for INT transfers that are being continued. ...@@ -114,7 +119,7 @@ re-submission for INT transfers that are being continued.
Just call Just call
int submit_urb(purb_t purb) int usb_submit_urb(purb_t purb)
It immediately returns, either with status 0 (request queued) or some It immediately returns, either with status 0 (request queued) or some
error code, usually caused by the following: error code, usually caused by the following:
...@@ -128,7 +133,7 @@ error code, usually caused by the following: ...@@ -128,7 +133,7 @@ error code, usually caused by the following:
- Invalid INT interval (-EINVAL) - Invalid INT interval (-EINVAL)
- More than one packet for INT (-EINVAL) - More than one packet for INT (-EINVAL)
After submission, urb->status is USB_ST_URB_PENDING. After submission, urb->status is USB_ST_URB_PENDING (-EINPROGRESS).
For isochronous endpoints, subsequent submitting of URBs to the same endpoint For isochronous endpoints, subsequent submitting of URBs to the same endpoint
with the ASAP flag result in a seamless ISO streaming. Exception: The with the ASAP flag result in a seamless ISO streaming. Exception: The
...@@ -142,18 +147,18 @@ independent of the transfer flags (implicitly ASAP). ...@@ -142,18 +147,18 @@ independent of the transfer flags (implicitly ASAP).
For an URB which you've submitted, but which hasn't been returned to For an URB which you've submitted, but which hasn't been returned to
your driver by the host controller, call your driver by the host controller, call
int unlink_urb(purb_t purb) int usb_unlink_urb(purb_t purb)
It removes the urb from the internal list and frees all allocated It removes the urb from the internal list and frees all allocated
HW descriptors. The status is changed to USB_ST_URB_KILLED. After HW descriptors. The status is changed to USB_ST_URB_KILLED. After
unlink_urb() returns, you can safely free the URB with free_urb(urb) usb_unlink_urb() returns, you can safely free the URB with usb_free_urb(urb)
and all other possibly associated data (urb->context etc.) and all other possibly associated data (urb->context etc.)
There is also an asynchronous unlink mode. To use this, set the There is also an asynchronous unlink mode. To use this, set the
the USB_ASYNC_UNLINK flag in urb->transfer flags before calling the USB_ASYNC_UNLINK flag in urb->transfer flags before calling
usb_unlink_urb(). When using async unlinking, the URB will not usb_unlink_urb(). When using async unlinking, the URB will not
normally be unlinked when unlink_urb() returns. Instead, wait for normally be unlinked when usb_unlink_urb() returns. Instead, wait
the completion handler to be called. for the completion handler to be called.
1.7. What about the completion handler? 1.7. What about the completion handler?
...@@ -187,13 +192,13 @@ in completion handlers. ...@@ -187,13 +192,13 @@ in completion handlers.
1.8. How to do isochronous (ISO) transfers? 1.8. How to do isochronous (ISO) transfers?
For ISO transfers you have to append the iso_packet_descriptor_t structure For ISO transfers you have to append the iso_packet_descriptor_t structure
to the URB for each frame you want to schedule. When using alloc_urb(n) to the URB for each frame you want to schedule. When using usb_alloc_urb(n)
(recommended), the isoframe-parameter n can be used to allocate the (recommended), the iso_packets parameter can be used to allocate the
structures for n frames. structures for iso_packets frames.
For each entry you have to specify the data offset for this frame (base is For each entry you have to specify the data offset for this frame (base is
transfer_buffer), and the length you want to write/expect to read. transfer_buffer), and the length you want to write/expect to read.
After completion, actual_length contains the actual transfered length and After completion, actual_length contains the actual transferred length and
status contains the resulting USB-status for the ISO transfer for this frame. status contains the resulting USB-status for the ISO transfer for this frame.
It is allowed to specify a varying length from frame to frame (e.g. for It is allowed to specify a varying length from frame to frame (e.g. for
audio synchronisation/adaptive transfer rates). You can also use the length audio synchronisation/adaptive transfer rates). You can also use the length
...@@ -217,7 +222,7 @@ for 1, 2, 4,... 128ms. Only one URB is allocated for each interrupt. After ...@@ -217,7 +222,7 @@ for 1, 2, 4,... 128ms. Only one URB is allocated for each interrupt. After
calling the completion handler, that URB is recycled by the host controller calling the completion handler, that URB is recycled by the host controller
driver (HCD). driver (HCD).
With the submission of one URB, the interrupt is scheduled until it is With the submission of one URB, the interrupt is scheduled until it is
canceled by unlink_urb. canceled by usb_unlink_urb.
The submit_urb()-call modifies urb->interval to the rounded value.
The usb_submit_urb() call modifies urb->interval to the implemented interval
value that is less than or equal to the requested interval value.
$Id: README.error-codes,v 1.1 1999/12/14 14:03:02 fliegl Exp $ Revised: 2000-Dec-05.
This is the documentation of (hopefully) all possible error codes (and This is the documentation of (hopefully) all possible error codes (and
their interpretation) that can be returned from the hostcontroller driver their interpretation) that can be returned from the host controller drivers
and from usbcore. and from usbcore.
NOTE: NOTE:
The USB_ST_* codes are deferred and are only listed for compatibility, new The USB_ST_* codes are deprecated and are only listed for compatibility;
software should use only -E* instead! new software should use only -E* instead!
...@@ -25,12 +25,16 @@ USB-specific: ...@@ -25,12 +25,16 @@ USB-specific:
-ENODEV specified USB-device or bus doesn't exist -ENODEV specified USB-device or bus doesn't exist
-ENXIO specified endpoint doesn't exist on the device USB_ST_REQUEST_ERROR
-ENXIO a) specified endpoint doesn't exist on the device
b) an URB is already queued to this endpoint and
USB_QUEUE_BULK wasn't used (UHCI HCDs only)
USB_ST_URB_INVALID_ERROR USB_ST_URB_INVALID_ERROR
-EINVAL a) Invalid transfer type specified (or not supported) -EINVAL a) Invalid transfer type specified (or not supported)
b) Invalid interrupt interval (0<=n<256) b) Invalid interrupt interval (0<=n<256)
c) more than one interrupt packet requested c) more than one interrupt packet requested
d) ISO: number_of_packets is < 0
-EAGAIN a) specified ISO start frame too early -EAGAIN a) specified ISO start frame too early
b) (using ISO-ASAP) too much scheduled for the future b) (using ISO-ASAP) too much scheduled for the future
...@@ -38,6 +42,7 @@ USB_ST_URB_INVALID_ERROR ...@@ -38,6 +42,7 @@ USB_ST_URB_INVALID_ERROR
-EFBIG too much ISO frames requested (currently uhci>900) -EFBIG too much ISO frames requested (currently uhci>900)
USB_ST_STALL
-EPIPE specified pipe-handle is already stalled -EPIPE specified pipe-handle is already stalled
-EMSGSIZE endpoint message size is zero, do interface/alternate setting -EMSGSIZE endpoint message size is zero, do interface/alternate setting
...@@ -59,7 +64,7 @@ USB_ST_NOERROR ...@@ -59,7 +64,7 @@ USB_ST_NOERROR
0 Transfer completed successfully 0 Transfer completed successfully
USB_ST_URB_KILLED USB_ST_URB_KILLED
-ENOENT URB was canceled by unlink_urb -ENOENT URB was canceled by usb_unlink_urb
USB_ST_URB_PENDING USB_ST_URB_PENDING
-EINPROGRESS URB still pending, no results yet -EINPROGRESS URB still pending, no results yet
...@@ -73,12 +78,28 @@ USB_ST_INTERNALERROR ...@@ -73,12 +78,28 @@ USB_ST_INTERNALERROR
USB_ST_CRC USB_ST_CRC
-EILSEQ CRC mismatch -EILSEQ CRC mismatch
USB_ST_STALL
-EPIPE a) babble detect -EPIPE a) babble detect
b) endpoint stalled b) endpoint stalled
USB_ST_BUFFERUNDERRUN USB_ST_BUFFEROVERRUN
-ENOST buffer error -ECOMM During an IN transfer, the host controller
received data from an endpoint faster than it
could be written to system memory
USB_ST_BUFFERUNDERRUN
-ENOSR During an OUT transfer, the host controller
could not retrieve data from system memory fast
enough to keep up with the USB data rate
USB_ST_DATAOVERRUN
-EOVERFLOW The amount of data returned by the endpoint was
greater than either the max packet size of the
endpoint or the remaining buffer size
USB_ST_DATAUNDERRUN
-EREMOTEIO The endpoint returned less than max packet size
and that amount did not fill the specified buffer
USB_ST_NORESPONSE USB_ST_NORESPONSE
USB_ST_TIMEOUT USB_ST_TIMEOUT
-ETIMEDOUT transfer timed out, NAK -ETIMEDOUT transfer timed out, NAK
...@@ -104,14 +125,7 @@ USB_ST_URB_INVALID_ERROR ...@@ -104,14 +125,7 @@ USB_ST_URB_INVALID_ERROR
************************************************************************** **************************************************************************
usb_register(): usb_register():
USB_ST_NOTSUPPORTED
-EINVAL error during registering new driver -EINVAL error during registering new driver
usb_terminate_bulk():
USB_ST_REMOVED
-ENODEV urb already removed
usb_get_*/usb_set_*(): usb_get_*/usb_set_*():
All USB errors (submit/status) can occur All USB errors (submit/status) can occur
...@@ -7,6 +7,7 @@ linux/Documentation/usb/*, see the following: ...@@ -7,6 +7,7 @@ linux/Documentation/usb/*, see the following:
Linux-USB project: http://www.linux-usb.org Linux-USB project: http://www.linux-usb.org
mirrors at http://www.suse.cz/development/linux-usb/ mirrors at http://www.suse.cz/development/linux-usb/
and http://usb.in.tum.de/linux-usb/ and http://usb.in.tum.de/linux-usb/
and http://it.linux-usb.org
Linux USB Guide: http://linux-usb.sourceforge.net Linux USB Guide: http://linux-usb.sourceforge.net
Linux-USB device overview (working devices and drivers): Linux-USB device overview (working devices and drivers):
http://www.qbik.ch/usb/devices/ http://www.qbik.ch/usb/devices/
......
...@@ -139,6 +139,9 @@ Digi AccelePort Driver ...@@ -139,6 +139,9 @@ Digi AccelePort Driver
(plus a parallel port) and 4 port USB serial converters. The driver (plus a parallel port) and 4 port USB serial converters. The driver
does NOT yet support the Digi AccelePort USB 8. does NOT yet support the Digi AccelePort USB 8.
This driver works under SMP with the usb-uhci driver. It does not
work under SMP with the uhci driver.
The driver is generally working, though we still have a few more ioctls The driver is generally working, though we still have a few more ioctls
to implement and final testing and debugging to do. The paralled port to implement and final testing and debugging to do. The paralled port
on the USB 2 is supported as a serial to parallel converter; in other on the USB 2 is supported as a serial to parallel converter; in other
...@@ -187,6 +190,12 @@ Empeg empeg-car Mark I/II Driver (empeg.c) ...@@ -187,6 +190,12 @@ Empeg empeg-car Mark I/II Driver (empeg.c)
This is an experimental driver to provide connectivity support for the This is an experimental driver to provide connectivity support for the
client synchronization tools for an Empeg empeg-car mp3 player. client synchronization tools for an Empeg empeg-car mp3 player.
Tips:
* Don't forget to create the device nodes for ttyUSB{0,1,2,...}
* modprobe empeg (modprobe is your friend)
* emptool --usb /dev/ttyUSB0 (or whatever you named your device node)
The driver is still pretty new, so some testing 'in the wild' would be The driver is still pretty new, so some testing 'in the wild' would be
helpful. :) helpful. :)
......
...@@ -1325,7 +1325,7 @@ M: pberger@brimson.com ...@@ -1325,7 +1325,7 @@ M: pberger@brimson.com
M: alborchers@steinerpoint.com M: alborchers@steinerpoint.com
L: linux-usb-users@lists.sourceforge.net L: linux-usb-users@lists.sourceforge.net
L: linux-usb-devel@lists.sourceforge.net L: linux-usb-devel@lists.sourceforge.net
S: Supported S: Maintained
USB SERIAL KEYSPAN DRIVER USB SERIAL KEYSPAN DRIVER
P: Hugh Blemings P: Hugh Blemings
...@@ -1351,6 +1351,13 @@ L: linux-usb-users@lists.sourceforge.net ...@@ -1351,6 +1351,13 @@ L: linux-usb-users@lists.sourceforge.net
L: linux-usb-devel@lists.sourceforge.net L: linux-usb-devel@lists.sourceforge.net
S: Maintained S: Maintained
USB SERIAL EMPEG EMPEG-CAR MARK I/II DRIVER
P: Gary Brubaker
M: xavyer@ix.netcom.com
L: linux-usb-users@lists.sourceforge.net
L: linux-usb-devel@lists.sourceforge.net
S: Maintained
USB MASS STORAGE DRIVER USB MASS STORAGE DRIVER
P: Matthew Dharm P: Matthew Dharm
M: mdharm-usb@one-eyed-alien.net M: mdharm-usb@one-eyed-alien.net
......
...@@ -631,43 +631,39 @@ end_move_self: # now we are at the right place ...@@ -631,43 +631,39 @@ end_move_self: # now we are at the right place
# appropriate # appropriate
# that was painless, now we enable a20 # that was painless, now we enable a20
#
# First, try the "fast A20 gate".
#
inb $0x92,%al
orb $0x02,%al # Fast A20 on
andb $0xfe,%al # Don't reset CPU!
outb %al,$0x92
#
# Now comes the tricky part: some machines don't have a KBC and thus
# would end up looping almost indefinitely here. HOWEVER, once we
# have done the first command write, we must not stop the sequence.
# Therefore, the first empty_8042 should check to see if the fast A20
# did the trick and stop its probing at that stage; but subsequent ones
# must not do so.
#
movb $0x01,%dl # A20-sensitive
call empty_8042 call empty_8042
jnz a20_wait # A20 already on?
movb $0xD1, %al # command write movb $0xD1, %al # command write
outb %al, $0x64 outb %al, $0x64
call empty_8042_no_a20_exit call empty_8042
movb $0xDF, %al # A20 on movb $0xDF, %al # A20 on
outb %al, $0x60 outb %al, $0x60
call empty_8042_no_a20_exit call empty_8042
#
# You must preserve the other bits here. Otherwise embarrasing things
# like laptops powering off on boot happen. Corrected version by Kira
# Brown from Linux 2.2
#
inb $0x92, %al #
orb $02, %al # "fast A20" version
outb %al, $0x92 # some chips have only this
# wait until a20 really *is* enabled; it can take a fair amount of # wait until a20 really *is* enabled; it can take a fair amount of
# time on certain systems; Toshiba Tecras are known to have this # time on certain systems; Toshiba Tecras are known to have this
# problem. The memory location used here (0x200) is the int 0x80 # problem. The memory location used here (0x200) is the int 0x80
# vector, which should be safe to use. # vector, which should be safe to use.
xorw %ax, %ax # segment 0x0000
movw %ax, %fs
decw %ax # segment 0xffff (HMA)
movw %ax, %gs
a20_wait: a20_wait:
call a20_test incw %ax # unused memory location <0xfff0
jz a20_wait movw %ax, %fs:(0x200) # we use the "int 0x80" vector
cmpw %gs:(0x210), %ax # and its corresponding HMA addr
je a20_wait # loop until no longer aliased
# make sure any possible coprocessor is properly reset.. # make sure any possible coprocessor is properly reset..
xorw %ax, %ax xorw %ax, %ax
...@@ -830,25 +826,21 @@ bootsect_panic_mess: ...@@ -830,25 +826,21 @@ bootsect_panic_mess:
# Some machines have delusions that the keyboard buffer is always full # Some machines have delusions that the keyboard buffer is always full
# with no keyboard attached... # with no keyboard attached...
# #
# If %dl is nonzero on entry, terminate with ZF=0 if A20 becomes alive, # If there is no keyboard controller, we will usually get 0xff
# otherwise terminate with ZF=1. # to all the reads. With each IO taking a microsecond and
# a timeout of 100,000 iterations, this can take about half a
# second ("delay" == outb to port 0x80). That should be ok,
# and should also be plenty of time for a real keyboard controller
# to empty.
#
empty_8042_no_a20_exit:
xorb %dl,%dl # Not A20-sensitive
empty_8042: empty_8042:
pushl %ecx pushl %ecx
movl $0x000FFFFF, %ecx movl $100000, %ecx
empty_8042_loop: empty_8042_loop:
decl %ecx decl %ecx
jz empty_8042_end_loop # ZF=1 jz empty_8042_end_loop
# Always call the test routine to keep delays constant
call a20_test
jz ignore_a20
and %dl,%dl
jnz empty_8042_end_loop # ZF=0
ignore_a20:
call delay call delay
...@@ -863,38 +855,10 @@ ignore_a20: ...@@ -863,38 +855,10 @@ ignore_a20:
no_output: no_output:
testb $2, %al # is input buffer full? testb $2, %al # is input buffer full?
jnz empty_8042_loop # yes - loop jnz empty_8042_loop # yes - loop
# ZF=1
empty_8042_end_loop: empty_8042_end_loop:
popl %ecx popl %ecx
ret ret
a20_test:
pushw %ax
pushw %cx
pushw %fs
pushw %gs
xorw %ax, %ax # segment 0x0000
movw %ax, %fs
decw %ax # segment 0xffff (HMA)
movw %ax, %gs
movw 0x100,%cx
movw %fs:(0x200),%ax # So we keep cycling...
pushw %ax # Be extra paranoid...
a20_loop:
incw %ax # unused memory location <0xfff0
movw %ax, %fs:(0x200) # we use the "int 0x80" vector
cmpw %gs:(0x210), %ax # and its corresponding HMA addr
jnz a20_ret # if ZF not set A20 is functional
loop a20_loop
a20_ret:
popw %fs:(0x200)
popw %gs
popw %fs
popw %cx
popw %ax
ret # if ZF set A20 is not operational
# Read the cmos clock. Return the seconds in al # Read the cmos clock. Return the seconds in al
gettime: gettime:
pushw %cx pushw %cx
...@@ -911,7 +875,6 @@ gettime: ...@@ -911,7 +875,6 @@ gettime:
# Delay is needed after doing I/O # Delay is needed after doing I/O
delay: delay:
outb %al,$0x80 # What the main kernel uses
outb %al,$0x80 outb %al,$0x80
ret ret
......
...@@ -220,66 +220,19 @@ void __init setup_local_APIC (void) ...@@ -220,66 +220,19 @@ void __init setup_local_APIC (void)
BUG(); BUG();
/* /*
* Set up LVT0, LVT1: * Intel recommends to set DFR, LDR and TPR before enabling
* * an APIC. See e.g. "AP-388 82489DX User's Manual" (Intel
* set up through-local-APIC on the BP's LINT0. This is not * document number 292116). So here it goes...
* strictly necessery in pure symmetric-IO mode, but sometimes
* we delegate interrupts to the 8259A.
*/
/*
* TODO: set up through-local-APIC from through-I/O-APIC? --macro
*/
value = apic_read(APIC_LVT0) & APIC_LVT_MASKED;
if (!smp_processor_id() && (pic_mode || !value)) {
value = APIC_DM_EXTINT;
printk("enabled ExtINT on CPU#%d\n", smp_processor_id());
} else {
value = APIC_DM_EXTINT | APIC_LVT_MASKED;
printk("masked ExtINT on CPU#%d\n", smp_processor_id());
}
apic_write_around(APIC_LVT0, value);
/*
* only the BP should see the LINT1 NMI signal, obviously.
*/ */
if (!smp_processor_id())
value = APIC_DM_NMI;
else
value = APIC_DM_NMI | APIC_LVT_MASKED;
if (!APIC_INTEGRATED(ver)) /* 82489DX */
value |= APIC_LVT_LEVEL_TRIGGER;
apic_write_around(APIC_LVT1, value);
if (APIC_INTEGRATED(ver)) { /* !82489DX */
maxlvt = get_maxlvt();
if (maxlvt > 3) /* Due to the Pentium erratum 3AP. */
apic_write(APIC_ESR, 0);
value = apic_read(APIC_ESR);
printk("ESR value before enabling vector: %08lx\n", value);
value = ERROR_APIC_VECTOR; // enables sending errors
apic_write_around(APIC_LVTERR, value);
/*
* spec says clear errors after enabling vector.
*/
if (maxlvt > 3)
apic_write(APIC_ESR, 0);
value = apic_read(APIC_ESR);
printk("ESR value after enabling vector: %08lx\n", value);
} else
printk("No ESR for 82489DX.\n");
/* /*
* Set Task Priority to 'accept all'. We never change this * Put the APIC into flat delivery mode.
* later on. * Must be "all ones" explicitly for 82489DX.
*/ */
value = apic_read(APIC_TASKPRI); apic_write_around(APIC_DFR, 0xffffffff);
value &= ~APIC_TPRI_MASK;
apic_write_around(APIC_TASKPRI, value);
/* /*
* Set up the logical destination ID and put the * Set up the logical destination ID.
* APIC into flat delivery mode.
*/ */
value = apic_read(APIC_LDR); value = apic_read(APIC_LDR);
value &= ~APIC_LDR_MASK; value &= ~APIC_LDR_MASK;
...@@ -287,9 +240,12 @@ void __init setup_local_APIC (void) ...@@ -287,9 +240,12 @@ void __init setup_local_APIC (void)
apic_write_around(APIC_LDR, value); apic_write_around(APIC_LDR, value);
/* /*
* Must be "all ones" explicitly for 82489DX. * Set Task Priority to 'accept all'. We never change this
* later on.
*/ */
apic_write_around(APIC_DFR, 0xffffffff); value = apic_read(APIC_TASKPRI);
value &= ~APIC_TPRI_MASK;
apic_write_around(APIC_TASKPRI, value);
/* /*
* Now that we are all set up, enable the APIC * Now that we are all set up, enable the APIC
...@@ -326,6 +282,56 @@ void __init setup_local_APIC (void) ...@@ -326,6 +282,56 @@ void __init setup_local_APIC (void)
*/ */
value |= SPURIOUS_APIC_VECTOR; value |= SPURIOUS_APIC_VECTOR;
apic_write_around(APIC_SPIV, value); apic_write_around(APIC_SPIV, value);
/*
* Set up LVT0, LVT1:
*
* set up through-local-APIC on the BP's LINT0. This is not
* strictly necessery in pure symmetric-IO mode, but sometimes
* we delegate interrupts to the 8259A.
*/
/*
* TODO: set up through-local-APIC from through-I/O-APIC? --macro
*/
value = apic_read(APIC_LVT0) & APIC_LVT_MASKED;
if (!smp_processor_id() && (pic_mode || !value)) {
value = APIC_DM_EXTINT;
printk("enabled ExtINT on CPU#%d\n", smp_processor_id());
} else {
value = APIC_DM_EXTINT | APIC_LVT_MASKED;
printk("masked ExtINT on CPU#%d\n", smp_processor_id());
}
apic_write_around(APIC_LVT0, value);
/*
* only the BP should see the LINT1 NMI signal, obviously.
*/
if (!smp_processor_id())
value = APIC_DM_NMI;
else
value = APIC_DM_NMI | APIC_LVT_MASKED;
if (!APIC_INTEGRATED(ver)) /* 82489DX */
value |= APIC_LVT_LEVEL_TRIGGER;
apic_write_around(APIC_LVT1, value);
if (APIC_INTEGRATED(ver)) { /* !82489DX */
maxlvt = get_maxlvt();
if (maxlvt > 3) /* Due to the Pentium erratum 3AP. */
apic_write(APIC_ESR, 0);
value = apic_read(APIC_ESR);
printk("ESR value before enabling vector: %08lx\n", value);
value = ERROR_APIC_VECTOR; // enables sending errors
apic_write_around(APIC_LVTERR, value);
/*
* spec says clear errors after enabling vector.
*/
if (maxlvt > 3)
apic_write(APIC_ESR, 0);
value = apic_read(APIC_ESR);
printk("ESR value after enabling vector: %08lx\n", value);
} else
printk("No ESR for 82489DX.\n");
} }
void __init init_apic_mappings(void) void __init init_apic_mappings(void)
......
...@@ -424,9 +424,12 @@ static int pcibios_lookup_irq(struct pci_dev *dev, int assign) ...@@ -424,9 +424,12 @@ static int pcibios_lookup_irq(struct pci_dev *dev, int assign)
DBG(" -> PIRQ %02x, mask %04x, excl %04x", pirq, mask, pirq_table->exclusive_irqs); DBG(" -> PIRQ %02x, mask %04x, excl %04x", pirq, mask, pirq_table->exclusive_irqs);
mask &= pcibios_irq_mask; mask &= pcibios_irq_mask;
/* Find the best IRQ to assign */ /*
newirq = 0; * Find the best IRQ to assign: use the one
if (assign) { * reported by the device if possible.
*/
newirq = dev->irq;
if (!newirq && assign) {
for (i = 0; i < 16; i++) { for (i = 0; i < 16; i++) {
if (!(mask & (1 << i))) if (!(mask & (1 << i)))
continue; continue;
...@@ -436,13 +439,18 @@ static int pcibios_lookup_irq(struct pci_dev *dev, int assign) ...@@ -436,13 +439,18 @@ static int pcibios_lookup_irq(struct pci_dev *dev, int assign)
newirq = i; newirq = i;
} }
} }
DBG(" -> newirq=%d", newirq);
} }
DBG(" -> newirq=%d", newirq);
/* Try to get current IRQ */ /* Try to get current IRQ */
if (r->get && (irq = r->get(pirq_router_dev, d, pirq))) { if (r->get && (irq = r->get(pirq_router_dev, d, pirq))) {
DBG(" -> got IRQ %d\n", irq); DBG(" -> got IRQ %d\n", irq);
msg = "Found"; msg = "Found";
/* We refuse to override the dev->irq information. Give a warning! */
if (dev->irq && dev->irq != irq) {
printk("IRQ routing conflict in pirq table! Try 'pci=autoirq'\n");
return 0;
}
} else if (newirq && r->set && (dev->class >> 8) != PCI_CLASS_DISPLAY_VGA) { } else if (newirq && r->set && (dev->class >> 8) != PCI_CLASS_DISPLAY_VGA) {
DBG(" -> assigning IRQ %d", newirq); DBG(" -> assigning IRQ %d", newirq);
if (r->set(pirq_router_dev, d, pirq, newirq)) { if (r->set(pirq_router_dev, d, pirq, newirq)) {
...@@ -576,19 +584,17 @@ void pcibios_penalize_isa_irq(int irq) ...@@ -576,19 +584,17 @@ void pcibios_penalize_isa_irq(int irq)
void pcibios_enable_irq(struct pci_dev *dev) void pcibios_enable_irq(struct pci_dev *dev)
{ {
if (!dev->irq) { u8 pin;
u8 pin; pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); if (pin && !pcibios_lookup_irq(dev, 1) && !dev->irq) {
if (pin && !pcibios_lookup_irq(dev, 1)) { char *msg;
char *msg; if (io_apic_assign_pci_irqs)
if (io_apic_assign_pci_irqs) msg = " Probably buggy MP table.";
msg = " Probably buggy MP table."; else if (pci_probe & PCI_BIOS_IRQ_SCAN)
else if (pci_probe & PCI_BIOS_IRQ_SCAN) msg = "";
msg = ""; else
else msg = " Please try using pci=biosirq.";
msg = " Please try using pci=biosirq."; printk(KERN_WARNING "PCI: No IRQ known for interrupt pin %c of device %s.%s\n",
printk(KERN_WARNING "PCI: No IRQ known for interrupt pin %c of device %s.%s\n", 'A' + pin - 1, dev->slot_name, msg);
'A' + pin - 1, dev->slot_name, msg);
}
} }
} }
...@@ -2172,7 +2172,7 @@ int get_cpuinfo(char * buffer) ...@@ -2172,7 +2172,7 @@ int get_cpuinfo(char * buffer)
"fpu_exception\t: %s\n" "fpu_exception\t: %s\n"
"cpuid level\t: %d\n" "cpuid level\t: %d\n"
"wp\t\t: %s\n" "wp\t\t: %s\n"
"flags\t:", "flags\t\t:",
c->fdiv_bug ? "yes" : "no", c->fdiv_bug ? "yes" : "no",
c->hlt_works_ok ? "no" : "yes", c->hlt_works_ok ? "no" : "yes",
c->f00f_bug ? "yes" : "no", c->f00f_bug ? "yes" : "no",
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
* enhanced by Bjoern Brauel and Roman Hodek * enhanced by Bjoern Brauel and Roman Hodek
*/ */
#include <linux/config.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
......
# $Id: Makefile,v 1.11 1999/10/17 19:55:22 harald Exp $
# #
# Makefile for MIPS-specific library files.. # Makefile for MIPS-specific library files..
# #
......
...@@ -3,8 +3,6 @@ ...@@ -3,8 +3,6 @@
* License. See the file "COPYING" in the main directory of this archive * License. See the file "COPYING" in the main directory of this archive
* for more details. * for more details.
* *
* $Id: memcpy.S,v 1.3 1998/07/10 01:14:49 ralf Exp $
*
* Unified implementation of memcpy, memmove and the __copy_user backend. * Unified implementation of memcpy, memmove and the __copy_user backend.
* For __rmemcpy and memmove an exception is always a kernel bug, therefore * For __rmemcpy and memmove an exception is always a kernel bug, therefore
* they're not protected. In order to keep the exception fixup routine * they're not protected. In order to keep the exception fixup routine
...@@ -410,6 +408,7 @@ LEAF(memmove) ...@@ -410,6 +408,7 @@ LEAF(memmove)
sltu t0, v0, a1 # dst + len < src -> non- sltu t0, v0, a1 # dst + len < src -> non-
bnez t0, __memcpy # overlapping, can use memcpy bnez t0, __memcpy # overlapping, can use memcpy
move v0, a0 /* return value */ move v0, a0 /* return value */
beqz a2, r_out
END(memmove) END(memmove)
LEAF(__rmemcpy) /* a0=dst a1=src a2=len */ LEAF(__rmemcpy) /* a0=dst a1=src a2=len */
......
/* /*
* include/asm-mips/types.h
*
* This file is subject to the terms and conditions of the GNU General Public * This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive * License. See the file "COPYING" in the main directory of this archive
* for more details. * for more details.
* *
* Copyright (C) 1998 by Ralf Baechle * Copyright (C) 1998 by Ralf Baechle
*
* $Id: memset.S,v 1.2 1998/04/25 17:01:45 ralf Exp $
*/ */
#include <asm/asm.h> #include <asm/asm.h>
#include <asm/offset.h> #include <asm/offset.h>
......
# $Id: Makefile,v 1.2 1999/11/19 20:35:22 ralf Exp $
# #
# Makefile for MIPS-specific library files.. # Makefile for MIPS-specific library files..
# #
......
...@@ -458,6 +458,7 @@ LEAF(memmove) ...@@ -458,6 +458,7 @@ LEAF(memmove)
sltu ta0, v0, a1 # dst + len < src -> non- sltu ta0, v0, a1 # dst + len < src -> non-
bnez ta0, __memcpy # overlapping, can use memcpy bnez ta0, __memcpy # overlapping, can use memcpy
move v0, a0 /* return value */ move v0, a0 /* return value */
beqz a2, r_out
END(memmove) END(memmove)
LEAF(__rmemcpy) /* a0=dst a1=src a2=len */ LEAF(__rmemcpy) /* a0=dst a1=src a2=len */
......
/* $Id: memset.S,v 1.3 2000/01/15 23:48:55 ralf Exp $ /*
*
* This file is subject to the terms and conditions of the GNU General Public * This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive * License. See the file "COPYING" in the main directory of this archive
* for more details. * for more details.
* *
* Copyright (C) 1998, 1999 by Ralf Baechle * Copyright (C) 1998, 1999, 2000 by Ralf Baechle
* Copyright (C) 1999 Silicon Graphics, Inc. * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
*/ */
#include <asm/asm.h> #include <asm/asm.h>
#include <asm/offset.h> #include <asm/offset.h>
#include <asm/regdef.h> #include <asm/regdef.h>
#include <asm/mipsregs.h>
#include <asm/stackframe.h>
#define EX(insn,reg,addr,handler) \ #define EX(insn,reg,addr,handler) \
9: insn reg, addr; \ 9: insn reg, addr; \
...@@ -34,8 +35,6 @@ ...@@ -34,8 +35,6 @@
* a1: char to fill with * a1: char to fill with
* a2: size of area to clear * a2: size of area to clear
*/ */
#include <asm/mipsregs.h>
#include <asm/stackframe.h>
.set noreorder .set noreorder
.align 5 .align 5
LEAF(memset) LEAF(memset)
......
#
# parisc/Makefile
#
# This file is included by the global makefile so that you can add your own
# architecture-specific flags and dependencies. Remember to do have actions
# for "archclean" and "archdep" for cleaning up and making dependencies for
# this architecture
#
# This file is subject to the terms and conditions of the GNU General Public
# License. See the file "COPYING" in the main directory of this archive
# for more details.
#
# Copyright (C) 1994 by Linus Torvalds
# Portions Copyright (C) 1999 The Puffin Group
#
# Modified for PA-RISC Linux by Paul Lahaie, Alex deVries,
# Mike Shaver, Helge Deller and Martin K. Petersen
#
FINAL_LD=$(CROSS_COMPILE)ld --warn-common --warn-section-align
CPP=$(CC) -E
OBJCOPY=$(CROSS_COMPILE)objcopy -O binary -R .note -R .comment -S
LDFLAGS =
LINKFLAGS =-T $(TOPDIR)/arch/parisc/vmlinux.lds $(LDFLAGS)
CFLAGS_PIPE := -pipe
CFLAGS_NSR := -fno-strength-reduce
CFLAGS := $(CFLAGS) -D__linux__ $(CFLAGS_PIPE) $(CFLAGS_NSR)
# These should be on for older toolchains or SOM toolchains that don't
# enable them by default.
CFLAGS += -mno-space-regs -mfast-indirect-calls
# If we become able to compile for specific platforms, this should be
# conditional on that.
CFLAGS += -mschedule=7200
# No fixed-point multiply
CFLAGS += -mdisable-fpregs
HEAD = arch/parisc/kernel/head.o
SUBDIRS := $(SUBDIRS) $(addprefix arch/parisc/, tools kernel mm lib hpux)
CORE_FILES := $(addprefix arch/parisc/, kernel/pdc_cons.o kernel/process.o \
lib/lib.a mm/mm.o kernel/kernel.o hpux/hpux.o) \
$(CORE_FILES) arch/parisc/kernel/init_task.o
LIBS := `$(CC) -print-libgcc-file-name` $(TOPDIR)/arch/parisc/lib/lib.a $(LIBS)
ifdef CONFIG_MATH_EMULATION
SUBDIRS := $(SUBDIRS) arch/parisc/math-emu
DRIVERS := $(DRIVERS) arch/parisc/math-emu/math.a
endif
ifdef CONFIG_KWDB
SUBDIRS := $(SUBDIRS) arch/parisc/kdb
DRIVERS := $(DRIVERS) arch/parisc/kdb/kdb.o
arch/parisc/kdb: dummy
$(MAKE) linuxsubdirs SUBDIRS=arch/parisc/kdb
endif
arch/parisc/kernel: dummy
$(MAKE) linuxsubdirs SUBDIRS=arch/parisc/kernel
arch/parisc/mm: dummy
$(MAKE) linuxsubdirs SUBDIRS=arch/parisc/mm
palo: vmlinux
export TOPDIR=`pwd`; export CONFIG_STI_CONSOLE=$(CONFIG_STI_CONSOLE); \
unset STRIP LDFLAGS CPP CPPFLAGS AFLAGS CFLAGS CC LD; cd ../palo && make lifimage
Image: palo
Image-clean:
ramdisk.o:
zImage: palo
bzImage: palo
compressed: zImage
install:
archclean:
archmrproper:
archdep:
#
# For a description of the syntax of this configuration file,
# see the Configure script.
#
mainmenu_name "Linux Kernel Configuration"
define_bool CONFIG_PARISC y
define_bool CONFIG_UID16 n
mainmenu_option next_comment
comment 'Code maturity level options'
bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL
endmenu
mainmenu_option next_comment
comment 'General options'
# bool 'Symmetric multi-processing support' CONFIG_SMP
define_bool CONFIG_SMP n
bool 'Kernel Debugger support' CONFIG_KWDB
# define_bool CONFIG_KWDB n
# bool 'GSC/Gecko bus support' CONFIG_GSC y
define_bool CONFIG_GSC y
bool 'U2/Uturn I/O MMU' CONFIG_IOMMU_CCIO y
bool 'LASI I/O support' CONFIG_GSC_LASI y
bool 'PCI bus support' CONFIG_PCI y
if [ "$CONFIG_PCI" = "y" ]; then
bool 'GSCtoPCI/DINO PCI support' CONFIG_GSC_DINO y
bool 'LBA/Elroy PCI support' CONFIG_PCI_LBA n
fi
if [ "$CONFIG_PCI_LBA" = "y" ]; then
define_bool CONFIG_IOSAPIC y
define_bool CONFIG_IOMMU_SBA y
fi
#
# if [ "$CONFIG_PCI_EPIC" = "y" ]; then...
#
endmenu
mainmenu_option next_comment
comment 'Loadable module support'
bool 'Enable loadable module support' CONFIG_MODULES
if [ "$CONFIG_MODULES" = "y" ]; then
bool 'Set version information on all symbols for modules' CONFIG_MODVERSIONS
bool 'Kernel module loader' CONFIG_KMOD
fi
endmenu
mainmenu_option next_comment
comment 'General setup'
bool 'Networking support' CONFIG_NET
bool 'System V IPC' CONFIG_SYSVIPC
bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
bool 'Sysctl support' CONFIG_SYSCTL
tristate 'Kernel support for SOM binaries' CONFIG_BINFMT_SOM
tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
tristate 'Kernel support for JAVA binaries (obsolete)' CONFIG_BINFMT_JAVA
fi
endmenu
##source drivers/parport/Config.in
mainmenu_option next_comment
comment 'Parallel port support'
tristate 'Parallel port support' CONFIG_PARPORT
if [ "$CONFIG_PARPORT" != "n" ]; then
if [ "$CONFIG_PCI" = "y" ]; then
dep_tristate ' PC-style hardware' CONFIG_PARPORT_PC $CONFIG_PARPORT
if [ "$CONFIG_PARPORT_PC" != "n" ]; then
bool ' Use FIFO/DMA if available' CONFIG_PARPORT_PC_FIFO
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
bool ' SuperIO chipset support (EXPERIMENTAL)' CONFIG_PARPORT_PC_SUPERIO
fi
fi
fi
if [ "$CONFIG_GSC_LASI" = "y" ]; then
dep_tristate ' LASI/ASP builtin parallel-port' CONFIG_PARPORT_GSC $CONFIG_PARPORT
else
define_tristate CONFIG_PARPORT_GSC n
fi
# If exactly one hardware type is selected then parport will optimise away
# support for loading any others. Defeat this if the user is keen.
bool ' Support foreign hardware' CONFIG_PARPORT_OTHER
bool ' IEEE 1284 transfer modes' CONFIG_PARPORT_1284
fi
endmenu
source drivers/block/Config.in
if [ "$CONFIG_NET" = "y" ]; then
source net/Config.in
fi
mainmenu_option next_comment
comment 'SCSI support'
tristate 'SCSI support' CONFIG_SCSI
if [ "$CONFIG_SCSI" != "n" ]; then
comment 'SCSI support type (disk, tape, CDrom)'
dep_tristate 'SCSI disk support' CONFIG_BLK_DEV_SD $CONFIG_SCSI
if [ "$CONFIG_BLK_DEV_SD" != "n" ]; then
int 'Maximum number of SCSI disks that can be loaded as modules' CONFIG_SD_EXTRA_DEVS 40
fi
dep_tristate 'SCSI tape support' CONFIG_CHR_DEV_ST $CONFIG_SCSI
dep_tristate 'SCSI CDROM support' CONFIG_BLK_DEV_SR $CONFIG_SCSI
if [ "$CONFIG_BLK_DEV_SR" != "n" ]; then
bool ' Enable vendor-specific extensions (for SCSI CDROM)' CONFIG_BLK_DEV_SR_VENDOR
int 'Maximum number of CDROM devices that can be loaded as modules' CONFIG_SR_EXTRA_DEVS 2
fi
dep_tristate 'SCSI generic support' CONFIG_CHR_DEV_SG $CONFIG_SCSI
comment 'Some SCSI devices (e.g. CD jukebox) support multiple LUNs'
bool 'Probe all LUNs on each SCSI device' CONFIG_SCSI_MULTI_LUN
bool 'Verbose SCSI error reporting (kernel size +=12K)' CONFIG_SCSI_CONSTANTS
mainmenu_option next_comment
comment 'SCSI low-level drivers'
if [ "$CONFIG_GSC_LASI" = "y" ]; then
dep_tristate 'Lasi SCSI support' CONFIG_SCSI_LASI $CONFIG_SCSI
dep_tristate 'Zalon SCSI support' CONFIG_SCSI_ZALON $CONFIG_SCSI
fi
if [ "$CONFIG_PCI" = "y" ]; then
dep_tristate 'SYM53C8XX SCSI support' CONFIG_SCSI_SYM53C8XX $CONFIG_SCSI
fi
if [ "$CONFIG_SCSI_ZALON" != "n" -o "$CONFIG_SCSI_SYM53C8XX" != "n" ]; then
int ' default tagged command queue depth' CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS 8
int ' maximum number of queued commands' CONFIG_SCSI_NCR53C8XX_MAX_TAGS 32
int ' synchronous transfers frequency in MHz' CONFIG_SCSI_NCR53C8XX_SYNC 20
bool ' enable profiling' CONFIG_SCSI_NCR53C8XX_PROFILE
bool ' use normal IO' CONFIG_SCSI_NCR53C8XX_IOMAPPED
fi
endmenu
fi
endmenu
if [ "$CONFIG_NET" = "y" ]; then
mainmenu_option next_comment
comment 'Network device support'
bool 'Network device support' CONFIG_NETDEVICES
if [ "$CONFIG_NETDEVICES" = "y" ]; then
if [ "$CONFIG_GSC_LASI" = "y" ]; then
tristate 'Lasi ethernet' CONFIG_LASI_82596
fi
source drivers/net/Config.in
fi
endmenu
fi
source drivers/char/Config.in
source fs/Config.in
mainmenu_option next_comment
comment 'Sound Drivers'
tristate 'Sound card support' CONFIG_SOUND
if [ "$CONFIG_SOUND" != "n" ]; then
source drivers/sound/Config.in
fi
endmenu
if [ "$CONFIG_VT" = "y" ]; then
mainmenu_option next_comment
comment 'Console drivers'
source drivers/video/Config.in
# bool 'IODC console' CONFIG_IODC_CONSOLE
bool 'STI console' CONFIG_STI_CONSOLE
if [ "$CONFIG_IODC_CONSOLE" = "n" ]; then
if [ "$CONFIG_GSC_PS2" = "y" ]; then
define_bool CONFIG_DUMMY_CONSOLE y
fi
fi
if [ "$CONFIG_STI_CONSOLE" = "y" ]; then
define_bool CONFIG_DUMMY_CONSOLE y
fi
endmenu
fi
# endmenu
mainmenu_option next_comment
comment 'Kernel hacking'
#bool 'Debug kmalloc/kfree' CONFIG_DEBUG_MALLOC
bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ
endmenu
#
# Automatically generated by make menuconfig: don't edit
#
CONFIG_PARISC=y
# CONFIG_UID16 is not set
#
# Code maturity level options
#
CONFIG_EXPERIMENTAL=y
#
# General options
#
# CONFIG_SMP is not set
# CONFIG_KWDB is not set
CONFIG_GSC=y
CONFIG_IOMMU_CCIO=y
CONFIG_GSC_LASI=y
CONFIG_PCI=y
CONFIG_GSC_DINO=y
CONFIG_PCI_LBA=y
CONFIG_IOSAPIC=y
CONFIG_IOMMU_SBA=y
#
# Loadable module support
#
CONFIG_MODULES=y
# CONFIG_MODVERSIONS is not set
CONFIG_KMOD=y
#
# General setup
#
CONFIG_NET=y
CONFIG_SYSVIPC=y
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
CONFIG_BINFMT_SOM=y
CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_MISC is not set
# CONFIG_BINFMT_JAVA is not set
#
# Parallel port support
#
CONFIG_PARPORT=y
# CONFIG_PARPORT_PC is not set
CONFIG_PARPORT_GSC=y
# CONFIG_PARPORT_OTHER is not set
# CONFIG_PARPORT_1284 is not set
#
# Block devices
#
# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_DEV_XD is not set
# CONFIG_PARIDE is not set
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
# CONFIG_BLK_DEV_LOOP is not set
# CONFIG_BLK_DEV_NBD is not set
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_SIZE=4096
CONFIG_BLK_DEV_INITRD=y
#
# Networking options
#
# CONFIG_PACKET is not set
# CONFIG_NETLINK is not set
# CONFIG_NETFILTER is not set
# CONFIG_FILTER is not set
CONFIG_UNIX=y
CONFIG_INET=y
# CONFIG_IP_MULTICAST is not set
# CONFIG_IP_ADVANCED_ROUTER is not set
CONFIG_IP_PNP=y
CONFIG_IP_PNP_BOOTP=y
# CONFIG_IP_PNP_RARP is not set
# CONFIG_NET_IPIP is not set
# CONFIG_NET_IPGRE is not set
# CONFIG_INET_ECN is not set
# CONFIG_SYN_COOKIES is not set
# CONFIG_IPV6 is not set
# CONFIG_KHTTPD is not set
# CONFIG_ATM is not set
# CONFIG_IPX is not set
# CONFIG_ATALK is not set
# CONFIG_DECNET is not set
# CONFIG_BRIDGE is not set
# CONFIG_X25 is not set
# CONFIG_LAPB is not set
# CONFIG_LLC is not set
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# QoS and/or fair queueing
#
# CONFIG_NET_SCHED is not set
#
# SCSI support
#
CONFIG_SCSI=y
CONFIG_BLK_DEV_SD=y
CONFIG_SD_EXTRA_DEVS=40
CONFIG_CHR_DEV_ST=y
CONFIG_BLK_DEV_SR=y
# CONFIG_BLK_DEV_SR_VENDOR is not set
CONFIG_SR_EXTRA_DEVS=2
CONFIG_CHR_DEV_SG=y
# CONFIG_SCSI_MULTI_LUN is not set
# CONFIG_SCSI_CONSTANTS is not set
#
# SCSI low-level drivers
#
CONFIG_SCSI_LASI=y
CONFIG_SCSI_ZALON=y
CONFIG_SCSI_SYM53C8XX=y
CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8
CONFIG_SCSI_NCR53C8XX_MAX_TAGS=32
CONFIG_SCSI_NCR53C8XX_SYNC=20
# CONFIG_SCSI_NCR53C8XX_PROFILE is not set
# CONFIG_SCSI_NCR53C8XX_IOMAPPED is not set
#
# Network device support
#
CONFIG_NETDEVICES=y
CONFIG_LASI_82596=y
#
# ARCnet devices
#
# CONFIG_ARCNET is not set
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
# CONFIG_NET_SB1000 is not set
#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
# CONFIG_NET_VENDOR_3COM is not set
# CONFIG_LANCE is not set
# CONFIG_NET_VENDOR_SMC is not set
# CONFIG_NET_VENDOR_RACAL is not set
# CONFIG_AT1700 is not set
# CONFIG_DEPCA is not set
# CONFIG_HP100 is not set
# CONFIG_NET_ISA is not set
CONFIG_NET_PCI=y
# CONFIG_PCNET32 is not set
# CONFIG_ADAPTEC_STARFIRE is not set
# CONFIG_AC3200 is not set
# CONFIG_APRICOT is not set
# CONFIG_CS89x0 is not set
# CONFIG_DE4X5 is not set
CONFIG_TULIP=y
# CONFIG_DGRS is not set
# CONFIG_DM9102 is not set
# CONFIG_EEPRO100 is not set
# CONFIG_LNE390 is not set
# CONFIG_NATSEMI is not set
# CONFIG_NE2K_PCI is not set
# CONFIG_NE3210 is not set
# CONFIG_ES3210 is not set
# CONFIG_RTL8129 is not set
# CONFIG_8139TOO is not set
# CONFIG_SIS900 is not set
# CONFIG_EPIC100 is not set
# CONFIG_SUNDANCE is not set
# CONFIG_TLAN is not set
# CONFIG_VIA_RHINE is not set
# CONFIG_WINBOND_840 is not set
# CONFIG_NET_POCKET is not set
#
# Ethernet (1000 Mbit)
#
# CONFIG_ACENIC is not set
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
# CONFIG_SK98LIN is not set
# CONFIG_FDDI is not set
# CONFIG_HIPPI is not set
# CONFIG_PLIP is not set
# CONFIG_PPP is not set
# CONFIG_SLIP is not set
#
# Wireless LAN (non-hamradio)
#
# CONFIG_NET_RADIO is not set
#
# Token Ring devices
#
# CONFIG_TR is not set
# CONFIG_NET_FC is not set
# CONFIG_RCPCI is not set
# CONFIG_SHAPER is not set
#
# Wan interfaces
#
# CONFIG_WAN is not set
#
# Character devices
#
CONFIG_VT=y
CONFIG_VT_CONSOLE=y
CONFIG_GSC_PS2=y
CONFIG_HIL=y
CONFIG_SERIAL=y
CONFIG_SERIAL_CONSOLE=y
CONFIG_SERIAL_GSC=y
# CONFIG_SERIAL_EXTENDED is not set
# CONFIG_SERIAL_NONSTANDARD is not set
CONFIG_UNIX98_PTYS=y
CONFIG_UNIX98_PTY_COUNT=256
CONFIG_PRINTER=y
# CONFIG_LP_CONSOLE is not set
# CONFIG_PPDEV is not set
#
# I2C support
#
# CONFIG_I2C is not set
#
# Mice
#
# CONFIG_BUSMOUSE is not set
# CONFIG_MOUSE is not set
#
# Joysticks
#
# CONFIG_JOYSTICK is not set
# CONFIG_QIC02_TAPE is not set
#
# Watchdog Cards
#
# CONFIG_WATCHDOG is not set
CONFIG_GENRTC=y
# CONFIG_INTEL_RNG is not set
# CONFIG_NVRAM is not set
# CONFIG_RTC is not set
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
#
# Ftape, the floppy tape device driver
#
# CONFIG_FTAPE is not set
# CONFIG_AGP is not set
# CONFIG_DRM is not set
#
# File systems
#
# CONFIG_QUOTA is not set
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
# CONFIG_ADFS_FS is not set
# CONFIG_ADFS_FS_RW is not set
# CONFIG_AFFS_FS is not set
# CONFIG_HFS_FS is not set
# CONFIG_BFS_FS is not set
# CONFIG_FAT_FS is not set
# CONFIG_MSDOS_FS is not set
# CONFIG_UMSDOS_FS is not set
# CONFIG_VFAT_FS is not set
# CONFIG_EFS_FS is not set
# CONFIG_JFFS_FS is not set
# CONFIG_CRAMFS is not set
# CONFIG_RAMFS is not set
CONFIG_ISO9660_FS=y
# CONFIG_JOLIET is not set
# CONFIG_MINIX_FS is not set
# CONFIG_NTFS_FS is not set
# CONFIG_NTFS_RW is not set
# CONFIG_HPFS_FS is not set
CONFIG_PROC_FS=y
# CONFIG_DEVFS_FS is not set
# CONFIG_DEVFS_MOUNT is not set
# CONFIG_DEVFS_DEBUG is not set
# CONFIG_DEVPTS_FS is not set
# CONFIG_QNX4FS_FS is not set
# CONFIG_QNX4FS_RW is not set
# CONFIG_ROMFS_FS is not set
CONFIG_EXT2_FS=y
# CONFIG_SYSV_FS is not set
# CONFIG_SYSV_FS_WRITE is not set
# CONFIG_UDF_FS is not set
# CONFIG_UDF_RW is not set
# CONFIG_UFS_FS is not set
# CONFIG_UFS_FS_WRITE is not set
#
# Network File Systems
#
# CONFIG_CODA_FS is not set
CONFIG_NFS_FS=y
# CONFIG_NFS_V3 is not set
CONFIG_ROOT_NFS=y
# CONFIG_NFSD is not set
# CONFIG_NFSD_V3 is not set
CONFIG_SUNRPC=y
CONFIG_LOCKD=y
# CONFIG_SMB_FS is not set
# CONFIG_NCP_FS is not set
# CONFIG_NCPFS_PACKET_SIGNING is not set
# CONFIG_NCPFS_IOCTL_LOCKING is not set
# CONFIG_NCPFS_STRONG is not set
# CONFIG_NCPFS_NFS_NS is not set
# CONFIG_NCPFS_OS2_NS is not set
# CONFIG_NCPFS_SMALLDOS is not set
# CONFIG_NCPFS_MOUNT_SUBDIR is not set
# CONFIG_NCPFS_NDS_DOMAINS is not set
# CONFIG_NCPFS_NLS is not set
# CONFIG_NCPFS_EXTRAS is not set
#
# Partition Types
#
# CONFIG_PARTITION_ADVANCED is not set
CONFIG_MSDOS_PARTITION=y
# CONFIG_NLS is not set
#
# Sound Drivers
#
# CONFIG_SOUND is not set
#
# Console drivers
#
#
# Frame-buffer support
#
# CONFIG_FB is not set
# CONFIG_STI_CONSOLE is not set
#
# Kernel hacking
#
CONFIG_MAGIC_SYSRQ=y
#
# Makefile for the linux kernel.
#
# 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 in the main makefile...
all: hpux.o
O_TARGET = hpux.o
O_OBJS = entry_hpux.o gate.o wrappers.o fs.o ioctl.o sys_hpux.o
.o.S: $(CC) -D__ASSEMBLY__ $(AFLAGS) -traditional -c $*.S -o $*.o
include $(TOPDIR)/Rules.make
This diff is collapsed.
/*
* linux/arch/parisc/kernel/sys_hpux.c
*
* implements HPUX syscalls.
*/
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/file.h>
#include <linux/smp_lock.h>
#include <linux/slab.h>
#include <asm/errno.h>
#include <asm/uaccess.h>
int hpux_execve(struct pt_regs *regs)
{
int error;
char *filename;
filename = getname((char *) regs->gr[26]);
error = PTR_ERR(filename);
if (IS_ERR(filename))
goto out;
error = do_execve(filename, (char **) regs->gr[25],
(char **)regs->gr[24], regs);
if (error == 0)
current->ptrace &= ~PT_DTRACE;
putname(filename);
out:
return error;
}
struct hpux_dirent {
long d_off_pad; /* we only have a 32-bit off_t */
long d_off;
ino_t d_ino;
short d_reclen;
short d_namlen;
char d_name[1];
};
struct getdents_callback {
struct hpux_dirent *current_dir;
struct hpux_dirent *previous;
int count;
int error;
};
#define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de)))
#define ROUND_UP(x) (((x)+sizeof(long)-1) & ~(sizeof(long)-1))
static int filldir(void * __buf, const char * name, int namlen, off_t offset, ino_t ino)
{
struct hpux_dirent * dirent;
struct getdents_callback * buf = (struct getdents_callback *) __buf;
int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1);
buf->error = -EINVAL; /* only used if we fail.. */
if (reclen > buf->count)
return -EINVAL;
dirent = buf->previous;
if (dirent)
put_user(offset, &dirent->d_off);
dirent = buf->current_dir;
buf->previous = dirent;
put_user(ino, &dirent->d_ino);
put_user(reclen, &dirent->d_reclen);
put_user(namlen, &dirent->d_namlen);
copy_to_user(dirent->d_name, name, namlen);
put_user(0, dirent->d_name + namlen);
((char *) dirent) += reclen;
buf->current_dir = dirent;
buf->count -= reclen;
return 0;
}
#undef NAME_OFFSET
#undef ROUND_UP
int hpux_getdents(unsigned int fd, struct hpux_dirent *dirent, unsigned int count)
{
struct file * file;
struct dentry * dentry;
struct inode * inode;
struct hpux_dirent * lastdirent;
struct getdents_callback buf;
int error;
lock_kernel();
error = -EBADF;
file = fget(fd);
if (!file)
goto out;
dentry = file->f_dentry;
if (!dentry)
goto out_putf;
inode = dentry->d_inode;
if (!inode)
goto out_putf;
buf.current_dir = dirent;
buf.previous = NULL;
buf.count = count;
buf.error = 0;
error = -ENOTDIR;
if (!file->f_op || !file->f_op->readdir)
goto out_putf;
/*
* Get the inode's semaphore to prevent changes
* to the directory while we read it.
*/
down(&inode->i_sem);
error = file->f_op->readdir(file, &buf, filldir);
up(&inode->i_sem);
if (error < 0)
goto out_putf;
error = buf.error;
lastdirent = buf.previous;
if (lastdirent) {
put_user(file->f_pos, &lastdirent->d_off);
error = count - buf.count;
}
out_putf:
fput(file);
out:
unlock_kernel();
return error;
}
int hpux_mount(const char *fs, const char *path, int mflag,
const char *fstype, const char *dataptr, int datalen)
{
return -ENOSYS;
}
static int cp_hpux_stat(struct inode * inode, struct hpux_stat64 * statbuf)
{
struct hpux_stat64 tmp;
unsigned int blocks, indirect;
memset(&tmp, 0, sizeof(tmp));
tmp.st_dev = kdev_t_to_nr(inode->i_dev);
tmp.st_ino = inode->i_ino;
tmp.st_mode = inode->i_mode;
tmp.st_nlink = inode->i_nlink;
tmp.st_uid = inode->i_uid;
tmp.st_gid = inode->i_gid;
tmp.st_rdev = kdev_t_to_nr(inode->i_rdev);
tmp.st_size = inode->i_size;
tmp.st_atime = inode->i_atime;
tmp.st_mtime = inode->i_mtime;
tmp.st_ctime = inode->i_ctime;
#define D_B 7
#define I_B (BLOCK_SIZE / sizeof(unsigned short))
if (!inode->i_blksize) {
blocks = (tmp.st_size + BLOCK_SIZE - 1) / BLOCK_SIZE;
if (blocks > D_B) {
indirect = (blocks - D_B + I_B - 1) / I_B;
blocks += indirect;
if (indirect > 1) {
indirect = (indirect - 1 + I_B - 1) / I_B;
blocks += indirect;
if (indirect > 1)
blocks++;
}
}
tmp.st_blocks = (BLOCK_SIZE / 512) * blocks;
tmp.st_blksize = BLOCK_SIZE;
} else {
tmp.st_blocks = inode->i_blocks;
tmp.st_blksize = inode->i_blksize;
}
return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;
}
/*
* Revalidate the inode. This is required for proper NFS attribute caching.
* Blatently copied wholesale from fs/stat.c
*/
static __inline__ int
do_revalidate(struct dentry *dentry)
{
struct inode * inode = dentry->d_inode;
if (inode->i_op && inode->i_op->revalidate)
return inode->i_op->revalidate(dentry);
return 0;
}
long hpux_stat64(const char *path, struct hpux_stat64 *buf)
{
struct nameidata nd;
int error;
lock_kernel();
error = user_path_walk(path, &nd);
if (!error) {
error = do_revalidate(nd.dentry);
if (!error)
error = cp_hpux_stat(nd.dentry->d_inode, buf);
path_release(&nd);
}
unlock_kernel();
return error;
}
long hpux_fstat64(unsigned int fd, struct hpux_stat64 *statbuf)
{
struct file * f;
int err = -EBADF;
lock_kernel();
f = fget(fd);
if (f) {
struct dentry * dentry = f->f_dentry;
err = do_revalidate(dentry);
if (!err)
err = cp_hpux_stat(dentry->d_inode, statbuf);
fput(f);
}
unlock_kernel();
return err;
}
long hpux_lstat64(char *filename, struct hpux_stat64 *statbuf)
{
struct nameidata nd;
int error;
lock_kernel();
error = user_path_walk_link(filename, &nd);
if (!error) {
error = do_revalidate(nd.dentry);
if (!error)
error = cp_hpux_stat(nd.dentry->d_inode, statbuf);
path_release(&nd);
}
unlock_kernel();
return error;
}
/* ------------------------------------------------------------------------------
*
* Linux/PARISC Project (http://www.thepuffingroup.com/parisc)
*
* System call entry code Copyright (c) Matthew Wilcox 1999 <willy@bofh.ai>
* Licensed under the GNU GPL.
* thanks to Philipp Rumpf, Mike Shaver and various others
* sorry about the wall, puffin..
*/
#define __ASSEMBLY__
#include <asm/assembly.h>
#include <asm/offset.h>
#include <asm/unistd.h>
#include <asm/errno.h>
#define __ASSEMBLY__
#include <asm/assembly.h> /* for STREG/LDREG */
.text
.import hpux_call_table
.import hpux_syscall_exit,code
.export hpux_gateway_page
.align 4096
hpux_gateway_page:
nop
mfsp %sr7,%r1 ;! we must set sr3 to the space
mtsp %r1,%sr3 ;! of the user before the gate
#ifdef __LP64__
#warning NEEDS WORK for 64-bit
#endif
ldw -64(%r30), %r28 ;! 8th argument
ldw -60(%r30), %r19 ;! 7th argument
ldw -56(%r30), %r20 ;! 6th argument
ldw -52(%r30), %r21 ;! 5th argument
gate .+8, %r0 ;! become privileged
mtsp %r0,%sr4 ;! get kernel space into sr4
mtsp %r0,%sr5 ;! get kernel space into sr5
mtsp %r0,%sr6 ;! get kernel space into sr6
mtsp %r0,%sr7 ;! get kernel space into sr7
mfctl %cr30,%r1 ;! get the kernel task ptr
mtctl %r0,%cr30 ;! zero it (flag)
STREG %r30,TASK_PT_GR30(%r1) ;! preserve userspace sp
STREG %r2,TASK_PT_GR2(%r1) ;! preserve rp
STREG %r27,TASK_PT_GR27(%r1) ;! user dp
STREG %r31,TASK_PT_GR31(%r1) ;! preserve syscall return ptr
loadgp ;! setup kernel dp
ldo TASK_SZ_ALGN+64(%r1),%r30 ;! set up kernel stack
stw %r21, -52(%r30) ;! 5th argument
stw %r20, -56(%r30) ;! 6th argument
stw %r19, -60(%r30) ;! 7th argument
stw %r28, -64(%r30) ;! 8th argument
ldil L%hpux_call_table, %r21
ldo R%hpux_call_table(%r21), %r21
comiclr,>>= __NR_HPUX_syscalls, %r22, %r0
b,n syscall_nosys
ldwx,s %r22(%r21), %r21
ldil L%hpux_syscall_exit,%r2
be 0(%sr7,%r21)
ldo R%hpux_syscall_exit(%r2),%r2
syscall_nosys:
ldil L%hpux_syscall_exit,%r1
be R%hpux_syscall_exit(%sr7,%r1)
ldo -ENOSYS(%r0),%r28
.align 4096
.export end_hpux_gateway_page
end_hpux_gateway_page:
/*
* linux/arch/parisc/hpux/ioctl.c
*
* implements some necessary HPUX ioctls.
*/
/*
* Supported ioctls:
* TCGETA
* TCSETA
* TCSETAW
* TCSETAF
* TCSBRK
* TCXONC
* TCFLSH
* TIOCGWINSZ
* TIOCSWINSZ
* TIOCGPGRP
* TIOCSPGRP
*/
#include <linux/smp_lock.h>
#include <asm/errno.h>
#include <asm/ioctl.h>
#include <asm/termios.h>
#include <asm/uaccess.h>
int sys_ioctl(unsigned int, unsigned int, unsigned long);
static int hpux_ioctl_t(int fd, unsigned long cmd, unsigned long arg)
{
int result = -EOPNOTSUPP;
int nr = _IOC_NR(cmd);
switch (nr) {
case 106:
result = sys_ioctl(fd, TIOCSWINSZ, arg);
break;
case 107:
result = sys_ioctl(fd, TIOCGWINSZ, arg);
break;
}
return result;
}
int hpux_ioctl(int fd, unsigned long cmd, unsigned long arg)
{
int result = -EOPNOTSUPP;
int type = _IOC_TYPE(cmd);
switch (type) {
case 'T':
/* Our structures are now compatible with HPUX's */
result = sys_ioctl(fd, cmd, arg);
break;
case 't':
result = hpux_ioctl_t(fd, cmd, arg);
break;
default:
/* If my mother ever sees this, I hope she disowns me.
* Take this out after NYLWE. */
result = sys_ioctl(fd, cmd, arg);
}
return result;
}
/*
* linux/arch/parisc/kernel/sys_hpux.c
*
* implements HPUX syscalls.
*/
#include <linux/sched.h>
#include <linux/smp_lock.h>
#include <linux/utsname.h>
#include <asm/errno.h>
#include <asm/uaccess.h>
unsigned long sys_brk(unsigned long addr);
unsigned long hpux_brk(unsigned long addr)
{
/* Sigh. Looks like HP/UX libc relies on kernel bugs. */
return sys_brk(addr + PAGE_SIZE);
}
int hpux_sbrk(void)
{
return -ENOSYS;
}
/* Random other syscalls */
int hpux_nice(int priority_change)
{
return -ENOSYS;
}
int hpux_ptrace(void)
{
return -ENOSYS;
}
int hpux_wait(int *stat_loc)
{
extern int sys_waitpid(int, int *, int);
return sys_waitpid(-1, stat_loc, 0);
}
#define _SC_CPU_VERSION 10001
#define _SC_OPEN_MAX 4
#define CPU_PA_RISC1_1 0x210
int hpux_sysconf(int which)
{
switch (which) {
case _SC_CPU_VERSION:
return CPU_PA_RISC1_1;
case _SC_OPEN_MAX:
return INT_MAX;
default:
return -EINVAL;
}
}
/*****************************************************************************/
#define HPUX_UTSLEN 9
#define HPUX_SNLEN 15
struct hpux_utsname {
char sysname[HPUX_UTSLEN];
char nodename[HPUX_UTSLEN];
char release[HPUX_UTSLEN];
char version[HPUX_UTSLEN];
char machine[HPUX_UTSLEN];
char idnumber[HPUX_SNLEN];
} ;
struct hpux_ustat {
int32_t f_tfree; /* total free (daddr_t) */
u_int32_t f_tinode; /* total inodes free (ino_t) */
char f_fname[6]; /* filsys name */
char f_fpack[6]; /* filsys pack name */
u_int32_t f_blksize; /* filsys block size (int) */
};
/*
* HPUX's utssys() call. It's a collection of miscellaneous functions,
* alas, so there's no nice way of splitting them up.
*/
/* This function is called from hpux_utssys(); HP-UX implements
* ustat() as an option to utssys().
*
* Now, struct ustat on HP-UX is exactly the same as on Linux, except
* that it contains one addition field on the end, int32_t f_blksize.
* So, we could have written this function to just call the Linux
* sys_ustat(), (defined in linux/fs/super.c), and then just
* added this additional field to the user's structure. But I figure
* if we're gonna be digging through filesystem structures to get
* this, we might as well just do the whole enchilada all in one go.
*
* So, most of this function is almost identical to sys_ustat().
* I have placed comments at the few lines changed or added, to
* aid in porting forward if and when sys_ustat() is changed from
* its form in kernel 2.2.5.
*/
static int hpux_ustat(dev_t dev, struct hpux_ustat *ubuf)
{
struct super_block *s;
struct hpux_ustat tmp; /* Changed to hpux_ustat */
struct statfs sbuf;
int err = -EINVAL;
lock_kernel();
s = get_super(to_kdev_t(dev));
if (s == NULL)
goto out;
err = vfs_statfs(s, &sbuf);
if (err)
goto out;
memset(&tmp,0,sizeof(struct hpux_ustat)); /* Changed to hpux_ustat */
tmp.f_tfree = (int32_t)sbuf.f_bfree;
tmp.f_tinode = (u_int32_t)sbuf.f_ffree;
tmp.f_blksize = (u_int32_t)sbuf.f_bsize; /* Added this line */
/* Changed to hpux_ustat: */
err = copy_to_user(ubuf,&tmp,sizeof(struct hpux_ustat)) ? -EFAULT : 0;
out:
unlock_kernel();
return err;
}
/* This function is called from hpux_utssys(); HP-UX implements
* uname() as an option to utssys().
*
* The form of this function is pretty much copied from sys_olduname(),
* defined in linux/arch/i386/kernel/sys_i386.c.
*/
/* TODO: Are these put_user calls OK? Should they pass an int?
* (I copied it from sys_i386.c like this.)
*/
static int hpux_uname(struct hpux_utsname *name)
{
int error;
if (!name)
return -EFAULT;
if (!access_ok(VERIFY_WRITE,name,sizeof(struct hpux_utsname)))
return -EFAULT;
down_read(&uts_sem);
error = __copy_to_user(&name->sysname,&system_utsname.sysname,HPUX_UTSLEN-1);
error |= __put_user(0,name->sysname+HPUX_UTSLEN-1);
error |= __copy_to_user(&name->nodename,&system_utsname.nodename,HPUX_UTSLEN-1);
error |= __put_user(0,name->nodename+HPUX_UTSLEN-1);
error |= __copy_to_user(&name->release,&system_utsname.release,HPUX_UTSLEN-1);
error |= __put_user(0,name->release+HPUX_UTSLEN-1);
error |= __copy_to_user(&name->version,&system_utsname.version,HPUX_UTSLEN-1);
error |= __put_user(0,name->version+HPUX_UTSLEN-1);
error |= __copy_to_user(&name->machine,&system_utsname.machine,HPUX_UTSLEN-1);
error |= __put_user(0,name->machine+HPUX_UTSLEN-1);
up_read(&uts_sem);
/* HP-UX utsname has no domainname field. */
/* TODO: Implement idnumber!!! */
#if 0
error |= __put_user(0,name->idnumber);
error |= __put_user(0,name->idnumber+HPUX_SNLEN-1);
#endif
error = error ? -EFAULT : 0;
return error;
}
int sys_sethostname(char *, int);
int sys_gethostname(char *, int);
/* Note: HP-UX just uses the old suser() function to check perms
* in this system call. We'll use capable(CAP_SYS_ADMIN).
*/
int hpux_utssys(char *ubuf, int n, int type)
{
int len;
int error;
switch( type ) {
case 0:
/* uname(): */
return( hpux_uname( (struct hpux_utsname *)ubuf ) );
break ;
case 1:
/* Obsolete (used to be umask().) */
return -EFAULT ;
break ;
case 2:
/* ustat(): */
return( hpux_ustat((dev_t)n, (struct hpux_ustat *)ubuf) );
break ;
case 3:
/* setuname():
*
* On linux (unlike HP-UX), utsname.nodename
* is the same as the hostname.
*
* sys_sethostname() is defined in linux/kernel/sys.c.
*/
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
/* Unlike Linux, HP-UX returns an error if n==0: */
if ( n <= 0 )
return -EINVAL ;
/* Unlike Linux, HP-UX truncates it if n is too big: */
len = (n <= __NEW_UTS_LEN) ? n : __NEW_UTS_LEN ;
return( sys_sethostname(ubuf, len) );
break ;
case 4:
/* sethostname():
*
* sys_sethostname() is defined in linux/kernel/sys.c.
*/
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
/* Unlike Linux, HP-UX returns an error if n==0: */
if ( n <= 0 )
return -EINVAL ;
/* Unlike Linux, HP-UX truncates it if n is too big: */
len = (n <= __NEW_UTS_LEN) ? n : __NEW_UTS_LEN ;
return( sys_sethostname(ubuf, len) );
break ;
case 5:
/* gethostname():
*
* sys_gethostname() is defined in linux/kernel/sys.c.
*/
/* Unlike Linux, HP-UX returns an error if n==0: */
if ( n <= 0 )
return -EINVAL ;
return( sys_gethostname(ubuf, n) );
break ;
case 6:
/* Supposedly called from setuname() in libc.
* TODO: When and why is this called?
* Is it ever even called?
*
* This code should look a lot like sys_sethostname(),
* defined in linux/kernel/sys.c. If that gets updated,
* update this code similarly.
*/
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
/* Unlike Linux, HP-UX returns an error if n==0: */
if ( n <= 0 )
return -EINVAL ;
/* Unlike Linux, HP-UX truncates it if n is too big: */
len = (n <= __NEW_UTS_LEN) ? n : __NEW_UTS_LEN ;
/**/
/* TODO: print a warning about using this? */
down_write(&uts_sem);
error = -EFAULT;
if (!copy_from_user(system_utsname.sysname, ubuf, len)) {
system_utsname.sysname[len] = 0;
error = 0;
}
up_write(&uts_sem);
return error;
break ;
case 7:
/* Sets utsname.release, if you're allowed.
* Undocumented. Used by swinstall to change the
* OS version, during OS updates. Yuck!!!
*
* This code should look a lot like sys_sethostname()
* in linux/kernel/sys.c. If that gets updated, update
* this code similarly.
*/
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
/* Unlike Linux, HP-UX returns an error if n==0: */
if ( n <= 0 )
return -EINVAL ;
/* Unlike Linux, HP-UX truncates it if n is too big: */
len = (n <= __NEW_UTS_LEN) ? n : __NEW_UTS_LEN ;
/**/
/* TODO: print a warning about this? */
down_write(&uts_sem);
error = -EFAULT;
if (!copy_from_user(system_utsname.release, ubuf, len)) {
system_utsname.release[len] = 0;
error = 0;
}
up_write(&uts_sem);
return error;
break ;
default:
/* This system call returns -EFAULT if given an unknown type.
* Why not -EINVAL? I don't know, it's just not what they did.
*/
return -EFAULT ;
}
}
int hpux_getdomainname(char *name, int len)
{
int nlen;
int err = -EFAULT;
down_read(&uts_sem);
nlen = strlen(system_utsname.domainname) + 1;
if (nlen < len)
len = nlen;
if(len > __NEW_UTS_LEN)
goto done;
if(copy_to_user(name, system_utsname.domainname, len))
goto done;
err = 0;
done:
up_read(&uts_sem);
return err;
}
int hpux_pipe(int *kstack_fildes)
{
int error;
lock_kernel();
error = do_pipe(kstack_fildes);
unlock_kernel();
return error;
}
/*------------------------------------------------------------------------------
* Native PARISC/Linux Project (http://www.puffingroup.com/parisc)
*
* HP-UX System Call Wrapper routines and System Call Return Path
*
* Copyright (C) 2000 Hewlett-Packard (John Marvin)
*
* 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
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* 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.
*/
#ifdef __LP64__
#warning Must be changed for PA64
#endif
#include <asm/offset.h>
.level 1.1
.text
#define __ASSEMBLY__
#include <asm/assembly.h>
#include <asm/signal.h>
/* These should probably go in a header file somewhere.
* They are duplicated in kernel/wrappers.S
* Possibly we should consider consolidating these
* register save/restore macros.
*/
.macro reg_save regs
#ifdef __LP64__
#warning NEEDS WORK for 64-bit
#endif
stw %r3, PT_GR3(\regs)
stw %r4, PT_GR4(\regs)
stw %r5, PT_GR5(\regs)
stw %r6, PT_GR6(\regs)
stw %r7, PT_GR7(\regs)
stw %r8, PT_GR8(\regs)
stw %r9, PT_GR9(\regs)
stw %r10,PT_GR10(\regs)
stw %r11,PT_GR11(\regs)
stw %r12,PT_GR12(\regs)
stw %r13,PT_GR13(\regs)
stw %r14,PT_GR14(\regs)
stw %r15,PT_GR15(\regs)
stw %r16,PT_GR16(\regs)
stw %r17,PT_GR17(\regs)
stw %r18,PT_GR18(\regs)
.endm
.macro reg_restore regs
ldw PT_GR3(\regs), %r3
ldw PT_GR4(\regs), %r4
ldw PT_GR5(\regs), %r5
ldw PT_GR6(\regs), %r6
ldw PT_GR7(\regs), %r7
ldw PT_GR8(\regs), %r8
ldw PT_GR9(\regs), %r9
ldw PT_GR10(\regs),%r10
ldw PT_GR11(\regs),%r11
ldw PT_GR12(\regs),%r12
ldw PT_GR13(\regs),%r13
ldw PT_GR14(\regs),%r14
ldw PT_GR15(\regs),%r15
ldw PT_GR16(\regs),%r16
ldw PT_GR17(\regs),%r17
ldw PT_GR18(\regs),%r18
.endm
.export hpux_fork_wrapper
.import sys_fork
hpux_fork_wrapper:
ldo TASK_REGS-TASK_SZ_ALGN-64(%r30),%r1 ;! get pt regs
;! pointer in task
reg_save %r1
stw %r2,-20(%r30)
ldo 64(%r30),%r30
stw %r2,PT_GR19(%r1) ;! save for child
stw %r30,PT_GR20(%r1) ;! save for child
ldil L%child_return,%r3
ldo R%child_return(%r3),%r3
stw %r3,PT_GR21(%r1) ;! save for child
ldw TASK_PT_GR30(%r1),%r25
copy %r1,%r24
bl sys_clone,%r2
ldi SIGCHLD,%r26
ldw -84(%r30),%r2
fork_return:
ldo -64(%r30),%r30
ldo TASK_REGS-TASK_SZ_ALGN-64(%r30),%r1 ;! get pt regs
reg_restore %r1
/*
* HP-UX wants pid (child gets parent pid, parent gets child pid)
* in r28 and a flag in r29 (r29 == 1 for child, 0 for parent).
* Linux fork returns 0 for child, pid for parent. Since HP-UX
* libc stub throws away parent pid and returns 0 for child,
* we'll just return 0 for parent pid now. Only applications
* that jump directly to the gateway page (not supported) will
* know the difference. We can fix this later if necessary.
*/
ldo -1024(%r0),%r1
comb,>>=,n %r28,%r1,fork_exit /* just let the syscall exit handle it */
or,= %r28,%r0,%r0
or,tr %r0,%r0,%r29 /* r28 <> 0, we are parent, set r29 to 0 */
ldo 1(%r0),%r29 /* r28 == 0, we are child, set r29 to 1 */
fork_exit:
bv %r0(%r2)
nop
/* Set the return value for the child */
child_return:
ldw TASK_PT_GR19-TASK_SZ_ALGN-128(%r30),%r2
b fork_return
copy %r0,%r28
.export hpux_execve_wrapper
.export hpux_execv_wrapper
.import hpux_execve
hpux_execv_wrapper:
copy %r0,%r24 /* NULL environment */
hpux_execve_wrapper:
ldo TASK_REGS-TASK_SZ_ALGN-64(%r30),%r1 ;! get pt regs
/*
* Do we need to save/restore r3-r18 here?
* I don't think so. why would new thread need old
* threads registers?
*/
/* Store arg0, arg1 and arg2 so that hpux_execve will find them */
stw %r26,PT_GR26(%r1)
stw %r25,PT_GR25(%r1)
stw %r24,PT_GR24(%r1)
stw %r2,-20(%r30)
ldo 64(%r30),%r30
bl hpux_execve,%r2
copy %r1,%arg0
ldo -64(%r30),%r30
ldw -20(%r30),%r2
/* If exec succeeded we need to load the args */
ldo -1024(%r0),%r1
comb,>>= %r28,%r1,exec_error
copy %r2,%r19
ldo -TASK_SZ_ALGN-64(%r30),%r1 ;! get task ptr
ldw TASK_PT_GR26(%r1),%r26
ldw TASK_PT_GR25(%r1),%r25
ldw TASK_PT_GR24(%r1),%r24
ldw TASK_PT_GR23(%r1),%r23
copy %r0,%r2 /* Flag to syscall_exit not to clear args */
exec_error:
bv %r0(%r19)
nop
.export hpux_pipe_wrapper
.import hpux_pipe
/* HP-UX expects pipefd's returned in r28 & r29 */
hpux_pipe_wrapper:
stw %r2,-20(%r30)
ldo 64(%r30),%r30
bl hpux_pipe,%r2
ldo -56(%r30),%r26 /* pass local array to hpux_pipe */
ldo -1024(%r0),%r1
comb,>>= %r28,%r1,pipe_exit /* let syscall exit handle it */
ldw -84(%r30),%r2
/* if success, load fd's from stack array */
ldw -56(%r30),%r28
ldw -52(%r30),%r29
pipe_exit:
bv %r0(%r2)
ldo -64(%r30),%r30
.export hpux_syscall_exit
.import syscall_exit
hpux_syscall_exit:
/*
*
* HP-UX call return conventions:
*
* if error:
* r22 = 1
* r28 = errno value
* r29 = secondary return value
* else
* r22 = 0
* r28 = return value
* r29 = secondary return value
*
* For now, we'll just check to see if r28 is < (unsigned long)-1024
* (to handle addresses > 2 Gb) and if so set r22 to zero. If not,
* we'll complement r28 and set r22 to 1. Wrappers will be
* needed for syscalls that care about the secondary return value.
* The wrapper may also need a way of avoiding the following code,
* but we'll deal with that when it becomes necessary.
*/
ldo -1024(%r0),%r1
comb,<< %r28,%r1,no_error
copy %r0,%r22
subi 0,%r28,%r28
ldo 1(%r0),%r22
no_error:
b syscall_exit
nop
#
# Makefile for the linux kernel.
#
# 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 in the main makefile...
all: kernel.o init_task.o pdc_cons.o process.o head.o
O_TARGET = kernel.o
O_OBJS =
# Object file lists.
obj-y :=
obj-m :=
obj-n :=
obj- :=
obj-y += cache.o setup.o traps.o time.o irq.o \
syscall.o entry.o sys_parisc.o pdc.o ptrace.o hardware.o \
inventory.o drivers.o semaphore.o pa7300lc.o pci-dma.o \
signal.o hpmc.o \
real1.o real2.o led.o parisc_ksyms.o
export-objs := parisc_ksyms.o
obj-$(CONFIG_PCI) += pci.o
obj-$(CONFIG_VT) += keyboard.o
obj-$(CONFIG_PCI_LBA) += lba_pci.o
# I/O SAPIC is also on IA64 platforms.
# The two could be merged into a common source some day.
obj-$(CONFIG_IOSAPIC) += iosapic.o
obj-$(CONFIG_IOMMU_SBA) += sba_iommu.o
# Only use one of them: ccio-rm-dma is for PCX-W systems *only*
# obj-$(CONFIG_IOMMU_CCIO) += ccio-rm-dma.o
obj-$(CONFIG_IOMMU_CCIO) += ccio-dma.o
.o.S: $(CC) -D__ASSEMBLY__ $(AFLAGS) -traditional -c $*.S -o $*.o
# Translate to Rules.make lists.
O_OBJS := $(filter-out $(export-objs), $(obj-y))
OX_OBJS := $(filter $(export-objs), $(obj-y))
M_OBJS := $(sort $(filter-out $(export-objs), $(obj-m)))
MX_OBJS := $(sort $(filter $(export-objs), $(obj-m)))
MI_OBJS := $(sort $(filter-out $(export-objs), $(int-m)))
MIX_OBJS := $(sort $(filter $(export-objs), $(int-m)))
include $(TOPDIR)/Rules.make
/* $Id: cache.c,v 1.4 2000/01/25 00:11:38 prumpf Exp $
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
* Copyright (C) 1999 Helge Deller (07-13-1999)
* Copyright (C) 1999 SuSE GmbH Nuernberg
* Copyright (C) 2000 Philipp Rumpf (prumpf@tux.org)
*
* Cache and TLB management
*
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <asm/pdc.h>
#include <asm/cache.h>
#include <asm/system.h>
#include <asm/page.h>
#include <asm/pgalloc.h>
struct pdc_cache_info cache_info;
#ifndef __LP64__
static struct pdc_btlb_info btlb_info;
#endif
void __flush_page_to_ram(unsigned long address)
{
__flush_dcache_range(address, PAGE_SIZE);
__flush_icache_range(address, PAGE_SIZE);
}
void flush_data_cache(void)
{
register unsigned long base = cache_info.dc_base;
register unsigned long count = cache_info.dc_count;
register unsigned long loop = cache_info.dc_loop;
register unsigned long stride = cache_info.dc_stride;
register unsigned long addr;
register long i, j;
for(i=0,addr=base; i<count; i++,addr+=stride)
for(j=0; j<loop; j++)
fdce(addr);
}
static inline void flush_data_tlb_space(void)
{
unsigned long base = cache_info.dt_off_base;
unsigned long count = cache_info.dt_off_count;
unsigned long stride = cache_info.dt_off_stride;
unsigned long loop = cache_info.dt_loop;
unsigned long addr;
long i,j;
for(i=0,addr=base; i<count; i++,addr+=stride)
for(j=0; j<loop; j++)
pdtlbe(addr);
}
void flush_data_tlb(void)
{
unsigned long base = cache_info.dt_sp_base;
unsigned long count = cache_info.dt_sp_count;
unsigned long stride = cache_info.dt_sp_stride;
unsigned long space;
unsigned long old_sr1;
long i;
old_sr1 = mfsp(1);
for(i=0,space=base; i<count; i++, space+=stride) {
mtsp(space,1);
flush_data_tlb_space();
}
mtsp(old_sr1, 1);
}
static inline void flush_instruction_tlb_space(void)
{
unsigned long base = cache_info.it_off_base;
unsigned long count = cache_info.it_off_count;
unsigned long stride = cache_info.it_off_stride;
unsigned long loop = cache_info.it_loop;
unsigned long addr;
long i,j;
for(i=0,addr=base; i<count; i++,addr+=stride)
for(j=0; j<loop; j++)
pitlbe(addr);
}
void flush_instruction_tlb(void)
{
unsigned long base = cache_info.it_sp_base;
unsigned long count = cache_info.it_sp_count;
unsigned long stride = cache_info.it_sp_stride;
unsigned long space;
unsigned long old_sr1;
unsigned int i;
old_sr1 = mfsp(1);
for(i=0,space=base; i<count; i++, space+=stride) {
mtsp(space,1);
flush_instruction_tlb_space();
}
mtsp(old_sr1, 1);
}
void __flush_tlb_space(unsigned long space)
{
unsigned long old_sr1;
old_sr1 = mfsp(1);
mtsp(space, 1);
flush_data_tlb_space();
flush_instruction_tlb_space();
mtsp(old_sr1, 1);
}
void flush_instruction_cache(void)
{
register unsigned long base = cache_info.ic_base;
register unsigned long count = cache_info.ic_count;
register unsigned long loop = cache_info.ic_loop;
register unsigned long stride = cache_info.ic_stride;
register unsigned long addr;
register long i, j;
unsigned long old_sr1;
old_sr1 = mfsp(1);
mtsp(0,1);
/*
* Note: fice instruction has 3 bit space field, so one must
* be specified (otherwise you are justing using whatever
* happens to be in sr0).
*/
for(i=0,addr=base; i<count; i++,addr+=stride)
for(j=0; j<loop; j++)
fice(addr);
mtsp(old_sr1, 1);
}
/* not yet ... fdc() needs to be implemented in cache.h !
void flush_datacache_range( unsigned int base, unsigned int end )
{
register long offset,offset_add;
offset_add = ( (1<<(cache_info.dc_conf.cc_block-1)) *
cache_info.dc_conf.cc_line ) << 4;
for (offset=base; offset<=end; offset+=offset_add)
fdc(space,offset);
fdc(space,end);
}
*/
/* flushes code and data-cache */
void flush_all_caches(void)
{
flush_instruction_cache();
flush_data_cache();
flush_instruction_tlb();
flush_data_tlb();
asm volatile("sync");
asm volatile("syncdma");
asm volatile("sync");
}
int get_cache_info(char *buffer)
{
char *p = buffer;
p += sprintf(p, "I-cache\t\t: %ld KB\n",
cache_info.ic_size/1024 );
p += sprintf(p, "D-cache\t\t: %ld KB (%s)%s\n",
cache_info.dc_size/1024,
(cache_info.dc_conf.cc_wt ? "WT":"WB"),
(cache_info.dc_conf.cc_sh ? " - shared I/D":"")
);
p += sprintf(p, "ITLB entries\t: %ld\n" "DTLB entries\t: %ld%s\n",
cache_info.it_size,
cache_info.dt_size,
cache_info.dt_conf.tc_sh ? " - shared with ITLB":""
);
#ifndef __LP64__
/* BTLB - Block TLB */
if (btlb_info.max_size==0) {
p += sprintf(p, "BTLB\t\t: not supported\n" );
} else {
p += sprintf(p,
"BTLB fixed\t: max. %d pages, pagesize=%d (%dMB)\n"
"BTLB fix-entr.\t: %d instruction, %d data (%d combined)\n"
"BTLB var-entr.\t: %d instruction, %d data (%d combined)\n",
btlb_info.max_size, (int)4096,
btlb_info.max_size>>8,
btlb_info.fixed_range_info.num_i,
btlb_info.fixed_range_info.num_d,
btlb_info.fixed_range_info.num_comb,
btlb_info.variable_range_info.num_i,
btlb_info.variable_range_info.num_d,
btlb_info.variable_range_info.num_comb
);
}
#endif
return p - buffer;
}
void __init
cache_init(void)
{
if(pdc_cache_info(&cache_info)<0)
panic("cache_init: pdc_cache_info failed");
#if 0
printk("ic_size %lx dc_size %lx it_size %lx pdc_cache_info %d*long pdc_cache_cf %d\n",
cache_info.ic_size,
cache_info.dc_size,
cache_info.it_size,
sizeof (struct pdc_cache_info) / sizeof (long),
sizeof (struct pdc_cache_cf)
);
#endif
#ifndef __LP64__
if(pdc_btlb_info(&btlb_info)<0) {
memset(&btlb_info, 0, sizeof btlb_info);
}
#endif
}
This diff is collapsed.
/*
* ccio-rm-dma.c:
* DMA management routines for first generation cache-coherent machines.
* "Real Mode" operation refers to U2/Uturn chip operation. The chip
* can perform coherency checks w/o using the I/O MMU. That's all we
* need until support for more than 4GB phys mem is needed.
*
* This is the trivial case - basically what x86 does.
*
* Drawbacks of using Real Mode are:
* o outbound DMA is slower since one isn't using the prefetching
* U2 can do for outbound DMA.
* o Ability to do scatter/gather in HW is also lost.
* o only known to work with PCX-W processor. (eg C360)
* (PCX-U/U+ are not coherent with U2 in real mode.)
*
*
* 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
*
* Original version/author:
* CVSROOT=:pserver:anonymous@198.186.203.37:/cvsroot/linux-parisc
* cvs -z3 co linux/arch/parisc/kernel/dma-rm.c
*
* (C) Copyright 2000 Philipp Rumpf <prumpf@tux.org>
*
*
* Adopted for The Puffin Group's parisc-linux port by Grant Grundler.
* (C) Copyright 2000 Grant Grundler <grundler@puffin.external.hp.com>
*
*/
#include <linux/types.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/string.h>
#include <linux/pci.h>
#include <asm/uaccess.h>
#include <asm/pgalloc.h>
#include <asm/io.h>
#include <asm/hardware.h>
#include <asm/page.h>
/* Only chose "ccio" since that's what HP-UX calls it....
** Make it easier for folks to migrate from one to the other :^)
*/
#define MODULE_NAME "ccio"
#define U2_IOA_RUNWAY 0x580
#define U2_BC_GSC 0x501
#define UTURN_IOA_RUNWAY 0x581
#define UTURN_BC_GSC 0x502
static int ccio_driver_callback(struct hp_device *, struct pa_iodc_driver *);
static struct pa_iodc_driver ccio_drivers_for[] = {
{HPHW_BCPORT, U2_BC_GSC, 0x0, 0xb, 0, 0x10,
DRIVER_CHECK_HVERSION +
DRIVER_CHECK_SVERSION + DRIVER_CHECK_HWTYPE,
MODULE_NAME, "U2 I/O MMU", (void *) ccio_driver_callback},
{HPHW_BCPORT, UTURN_BC_GSC, 0x0, 0xb, 0, 0x10,
DRIVER_CHECK_HVERSION +
DRIVER_CHECK_SVERSION + DRIVER_CHECK_HWTYPE,
MODULE_NAME, "Uturn I/O MMU", (void *) ccio_driver_callback},
{0,0,0,0,0,0,
0,
(char *) NULL, (char *) NULL, (void *) NULL }
};
#define IS_U2(id) ( \
(((id)->hw_type == HPHW_IOA) && ((id)->hversion == U2_IOA_RUNWAY)) || \
(((id)->hw_type == HPHW_BCPORT) && ((id)->hversion == U2_BC_GSC)) \
)
#define IS_UTURN(id) ( \
(((id)->hw_type == HPHW_IOA) && ((id)->hversion == UTURN_IOA_RUNWAY)) || \
(((id)->hw_type == HPHW_BCPORT) && ((id)->hversion == UTURN_BC_GSC)) \
)
void __init ccio_init(void)
{
register_driver(ccio_drivers_for);
}
static int ccio_dma_supported( struct pci_dev *dev, dma_addr_t mask)
{
if (dev == NULL) {
printk(MODULE_NAME ": EISA/ISA/et al not supported\n");
BUG();
return(0);
}
dev->dma_mask = mask; /* save it */
/* only support 32-bit devices (ie PCI/GSC) */
return((int) (mask >= 0xffffffffUL));
}
static void *ccio_alloc_consistent(struct pci_dev *dev, size_t size,
dma_addr_t *handle)
{
void *ret;
ret = (void *)__get_free_pages(GFP_ATOMIC, get_order(size));
if (ret != NULL) {
memset(ret, 0, size);
*handle = virt_to_phys(ret);
}
return ret;
}
static void ccio_free_consistent(struct pci_dev *dev, size_t size,
void *vaddr, dma_addr_t handle)
{
free_pages((unsigned long)vaddr, get_order(size));
}
static dma_addr_t ccio_map_single(struct pci_dev *dev, void *ptr, size_t size,
int direction)
{
return virt_to_phys(ptr);
}
static void ccio_unmap_single(struct pci_dev *dev, dma_addr_t dma_addr,
size_t size, int direction)
{
/* Nothing to do */
}
static int ccio_map_sg(struct pci_dev *dev, struct scatterlist *sglist, int nents, int direction)
{
int tmp = nents;
/* KISS: map each buffer seperately. */
while (nents) {
sg_dma_address(sglist) = ccio_map_single(dev, sglist->address, sglist->length, direction);
sg_dma_len(sglist) = sglist->length;
nents--;
sglist++;
}
return tmp;
}
static void ccio_unmap_sg(struct pci_dev *dev, struct scatterlist *sglist, int nents, int direction)
{
#if 0
while (nents) {
ccio_unmap_single(dev, sg_dma_address(sglist), sg_dma_len(sglist), direction);
nents--;
sglist++;
}
return;
#else
/* Do nothing (copied from current ccio_unmap_single() :^) */
#endif
}
static struct pci_dma_ops ccio_ops = {
ccio_dma_supported,
ccio_alloc_consistent,
ccio_free_consistent,
ccio_map_single,
ccio_unmap_single,
ccio_map_sg,
ccio_unmap_sg,
NULL, /* dma_sync_single : NOP for U2 */
NULL, /* dma_sync_sg : ditto */
};
/*
** Determine if u2 should claim this chip (return 0) or not (return 1).
** If so, initialize the chip and tell other partners in crime they
** have work to do.
*/
static int
ccio_driver_callback(struct hp_device *d, struct pa_iodc_driver *dri)
{
printk("%s found %s at 0x%p\n", dri->name, dri->version, d->hpa);
/*
** FIXME - should check U2 registers to verify it's really running
** in "Real Mode".
*/
#if 0
/* will need this for "Virtual Mode" operation */
ccio_hw_init(ccio_dev);
ccio_common_init(ccio_dev);
#endif
hppa_dma_ops = &ccio_ops;
return 0;
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/init.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
#include <asm/pgalloc.h>
static struct vm_area_struct init_mmap = INIT_MMAP;
static struct fs_struct init_fs = INIT_FS;
static struct files_struct init_files = INIT_FILES;
static struct signal_struct init_signals = INIT_SIGNALS;
struct mm_struct init_mm = INIT_MM(init_mm);
/*
* Initial task structure.
*
* We need to make sure that this is 16384-byte aligned due to the
* way process stacks are handled. This is done by having a special
* "init_task" linker map entry..
*/
union task_union init_task_union
__attribute__((section("init_task"), aligned(4096))) = { INIT_TASK(init_task_union.task) };
unsigned long swapper_pg_dir[PTRS_PER_PGD] __attribute__ ((aligned(4096))) = { 0, };
#ifdef __LP64__
unsigned long pmd0[PTRS_PER_PMD] __attribute__ ((aligned(4096))) = { 0, };
#endif
unsigned long pg0[PT_INITIAL * PTRS_PER_PTE] __attribute__ ((aligned(4096))) = { 0, };
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.
#
# Makefile for parisc-specific library files..
#
L_TARGET = lib.a
L_OBJS = lusercopy.o bitops.o checksum.o
.S.o:
$(CC) -D__ASSEMBLY__ $(AFLAGS) -traditional -c $< -o $*.o
include $(TOPDIR)/Rules.make
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.
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.
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