Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
159f5e24
Commit
159f5e24
authored
Nov 23, 2007
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Import 2.3.35pre4
parent
587f241d
Changes
23
Hide whitespace changes
Inline
Side-by-side
Showing
23 changed files
with
796 additions
and
374 deletions
+796
-374
Documentation/networking/sis900.txt
Documentation/networking/sis900.txt
+18
-10
arch/i386/config.in
arch/i386/config.in
+1
-0
arch/i386/defconfig
arch/i386/defconfig
+1
-1
arch/i386/kernel/Makefile
arch/i386/kernel/Makefile
+4
-0
arch/i386/kernel/acpi.c
arch/i386/kernel/acpi.c
+123
-63
arch/i386/kernel/irq.c
arch/i386/kernel/irq.c
+35
-0
arch/i386/kernel/setup.c
arch/i386/kernel/setup.c
+1
-1
drivers/block/rd.c
drivers/block/rd.c
+60
-8
drivers/misc/Config.in
drivers/misc/Config.in
+0
-2
drivers/misc/Makefile
drivers/misc/Makefile
+0
-4
drivers/net/sis900.c
drivers/net/sis900.c
+41
-28
drivers/net/sis900.h
drivers/net/sis900.h
+2
-2
drivers/pci/pci.c
drivers/pci/pci.c
+259
-146
drivers/pcmcia/pci_socket.h
drivers/pcmcia/pci_socket.h
+2
-1
drivers/pcmcia/yenta.c
drivers/pcmcia/yenta.c
+128
-45
drivers/pcmcia/yenta.h
drivers/pcmcia/yenta.h
+2
-0
drivers/scsi/scsi_lib.c
drivers/scsi/scsi_lib.c
+2
-0
drivers/usb/acm.c
drivers/usb/acm.c
+110
-61
fs/proc/base.c
fs/proc/base.c
+2
-2
include/linux/i2c-old.h
include/linux/i2c-old.h
+1
-0
include/linux/interrupt.h
include/linux/interrupt.h
+1
-0
include/linux/pci.h
include/linux/pci.h
+1
-0
init/main.c
init/main.c
+2
-0
No files found.
Documentation/networking/sis900.txt
View file @
159f5e24
SiS 900/7016 Fast Ethernet Device Driver
by Ollie Lho (ollie@sis.com.tw)
November 4, 1999. Document Revision: 0.
1
November 4, 1999. Document Revision: 0.
2
This document gives some information on installation and usage of SiS
900/7016 device driver under Linux.
...
...
@@ -17,7 +17,7 @@
4. Tested Environment
5. Files in This
R
ackage
5. Files in This
P
ackage
6. Installation
...
...
@@ -111,9 +111,11 @@
9. Names of variables were changed to be more consistent.
10. Clean up of auo-negotiation and timer code.
10.
Clean up of auo-negotiation and timer code.
11. Automatic detection and change of PHY on the fly.
11.
Automatic detection and change of PHY on the fly.
4. Tested Environment
...
...
@@ -137,7 +139,7 @@
o Samba version 2.0.3
5. Files in This
R
ackage
5. Files in This
P
ackage
In the package you can find these files:
...
...
@@ -157,10 +159,16 @@
6. Installation
Before trying to install the driver, be sure to get the latest
revision from SiS' Home Page. If you have no prior experience in
networking under Linux, please read Ethernet HOWTO and Networking
HOWTO available from Linux Documentation Project (LDP).
Silicon Integrated System Corp. is cooperating closely with core Linux
Kernel developers. The revisions of SiS 900 driver are distributed by
the usuall channels for kernel tar files and patches. Those kernel tar
files for official kernel and patches for kernel pre-release can be
download at official kernel ftp site
<http://ftp.kernel.org/pub/linux/kernel/> and its mirrors. The 1.06
revision can be found in kernel version later than 2.3.15 and
pre-2.2.14. If you have no prior experience in networking under
Linux, please read Ethernet HOWTO and Networking HOWTO available from
Linux Documentation Project (LDP).
The installation procedure are different according to your kernel
versions.
...
...
@@ -244,6 +252,7 @@
sis900.c: v1.06 11/04/99
eth0: SiS 900 PCI Fast Ethernet at 0xd000, IRQ 10, 00:00:e8:83:7f:a4.
eth0: SiS 900 Internal MII PHY transceiver found at address 1.
eth0: Using SiS 900 Internal MII PHY as default
...
...
@@ -269,7 +278,6 @@
eth0: Using SiS 900 Internal MII PHY as default
eth0: Media Link On 100mbps full-duplex
...
...
arch/i386/config.in
View file @
159f5e24
...
...
@@ -119,6 +119,7 @@ tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
source drivers/parport/Config.in
bool 'ACPI support' CONFIG_ACPI
bool 'Advanced Power Management BIOS support' CONFIG_APM
if [ "$CONFIG_APM" != "n" ]; then
bool ' Ignore USER SUSPEND' CONFIG_APM_IGNORE_USER_SUSPEND
...
...
arch/i386/defconfig
View file @
159f5e24
...
...
@@ -71,6 +71,7 @@ CONFIG_BINFMT_AOUT=y
CONFIG_BINFMT_ELF=y
CONFIG_BINFMT_MISC=y
# CONFIG_PARPORT is not set
CONFIG_ACPI=y
# CONFIG_APM is not set
#
...
...
@@ -405,7 +406,6 @@ CONFIG_DRM_TDFX=y
#
# Misc devices
#
CONFIG_ACPI=y
#
# Filesystems
...
...
arch/i386/kernel/Makefile
View file @
159f5e24
...
...
@@ -39,6 +39,10 @@ else
endif
endif
ifeq
($(CONFIG_ACPI),y)
OX_OBJS
+=
acpi.o
endif
ifeq
($(CONFIG_APM),y)
OX_OBJS
+=
apm.o
else
...
...
drivers/misc
/acpi.c
→
arch/i386/kernel
/acpi.c
View file @
159f5e24
...
...
@@ -110,6 +110,8 @@ static spinlock_t acpi_devs_lock = SPIN_LOCK_UNLOCKED;
static
LIST_HEAD
(
acpi_devs
);
/* Make it impossible to enter C2/C3 until after we've initialized */
static
unsigned
long
acpi_enter_lvl2_lat
=
ACPI_INFINITE_LAT
;
static
unsigned
long
acpi_enter_lvl3_lat
=
ACPI_INFINITE_LAT
;
static
unsigned
long
acpi_p_lvl2_lat
=
ACPI_INFINITE_LAT
;
static
unsigned
long
acpi_p_lvl3_lat
=
ACPI_INFINITE_LAT
;
...
...
@@ -636,87 +638,143 @@ static int acpi_disable(struct acpi_facp *facp)
return
0
;
}
static
inline
int
bm_activity
(
void
)
{
return
0
&&
acpi_read_pm1_status
(
acpi_facp
)
&
ACPI_BM
;
}
static
inline
void
clear_bm_activity
(
void
)
{
acpi_write_pm1_status
(
acpi_facp
,
ACPI_BM
);
}
static
void
sleep_on_busmaster
(
void
)
{
u32
pm1_cntr
=
acpi_read_pm1_control
(
acpi_facp
);
if
(
pm1_cntr
&
ACPI_BM_RLD
)
{
pm1_cntr
&=
~
ACPI_BM_RLD
;
acpi_write_pm1_control
(
acpi_facp
,
pm1_cntr
);
}
}
static
void
wake_on_busmaster
(
void
)
{
u32
pm1_cntr
=
acpi_read_pm1_control
(
acpi_facp
);
if
(
!
(
pm1_cntr
&
ACPI_BM_RLD
))
{
pm1_cntr
|=
ACPI_BM_RLD
;
acpi_write_pm1_control
(
acpi_facp
,
pm1_cntr
);
}
clear_bm_activity
();
}
/*
* Idle loop (uniprocessor only)
*/
static
void
acpi_idle_handler
(
void
)
{
static
int
sleep_level
=
1
;
u32
pm1_cnt
,
timer
,
pm2_cnt
,
bm_active
;
unsigned
long
time
;
// return to C0 on bus master request (necessary for C3 only)
pm1_cnt
=
acpi_read_pm1_control
(
acpi_facp
);
if
(
sleep_level
==
3
)
{
if
(
!
(
pm1_cnt
&
ACPI_BM_RLD
))
{
pm1_cnt
|=
ACPI_BM_RLD
;
acpi_write_pm1_control
(
acpi_facp
,
pm1_cnt
);
}
}
else
{
if
(
pm1_cnt
&
ACPI_BM_RLD
)
{
pm1_cnt
&=
~
ACPI_BM_RLD
;
acpi_write_pm1_control
(
acpi_facp
,
pm1_cnt
);
}
}
// clear bus master activity flag
acpi_write_pm1_status
(
acpi_facp
,
ACPI_BM
)
;
if
(
!
acpi_facp
->
pm_tmr
||
!
acpi_p_blk
)
goto
not_initialized
;
// get current time
timer
=
acpi_facp
->
pm_tmr
;
time
=
inl
(
timer
);
// sleep
switch
(
sleep_level
)
{
case
1
:
__asm__
__volatile__
(
"sti ; hlt"
:
:
:
"memory"
);
break
;
case
2
:
inb
(
acpi_p_blk
+
ACPI_P_LVL2
);
break
;
case
3
:
pm2_cnt
=
acpi_facp
->
pm2_cnt
;
if
(
pm2_cnt
)
{
/* Disable PCI arbitration while sleeping,
to avoid DMA corruption? */
cli
();
outb
(
inb
(
pm2_cnt
)
|
ACPI_ARB_DIS
,
pm2_cnt
);
inb
(
acpi_p_blk
+
ACPI_P_LVL3
);
outb
(
inb
(
pm2_cnt
)
&
~
ACPI_ARB_DIS
,
pm2_cnt
);
sti
();
}
else
{
inb
(
acpi_p_blk
+
ACPI_P_LVL3
);
}
break
;
/*
* start from the previous sleep level..
*/
if
(
sleep_level
==
1
)
goto
sleep1
;
if
(
sleep_level
==
2
||
bm_activity
())
goto
sleep2
;
sleep3:
sleep_level
=
3
;
if
(
!
acpi_p_lvl3_tested
)
{
printk
(
"ACPI C3 works
\n
"
);
acpi_p_lvl3_tested
=
1
;
}
wake_on_busmaster
();
if
(
acpi_facp
->
pm2_cnt
)
goto
sleep3_with_arbiter
;
// calculate time spent sleeping
time
=
(
inl
(
timer
)
-
time
)
&
ACPI_TMR_MASK
;
for
(;;)
{
unsigned
long
time
;
__cli
();
if
(
current
->
need_resched
)
goto
out
;
time
=
inl
(
acpi_facp
->
pm_tmr
);
inb
(
acpi_p_blk
+
ACPI_P_LVL3
);
time
=
inl
(
acpi_facp
->
pm_tmr
)
-
time
;
__sti
();
if
(
time
>
acpi_p_lvl3_lat
||
bm_activity
())
goto
sleep2
;
}
// check for bus master activity
bm_active
=
(
acpi_read_pm1_status
(
acpi_facp
)
&
ACPI_BM
);
sleep3_with_arbiter:
for
(;;)
{
unsigned
long
time
;
unsigned
int
pm2_cntr
=
acpi_facp
->
pm2_cnt
;
__cli
();
if
(
current
->
need_resched
)
goto
out
;
time
=
inl
(
acpi_facp
->
pm_tmr
);
outb
(
inb
(
pm2_cntr
)
|
ACPI_ARB_DIS
,
pm2_cntr
);
inb
(
acpi_p_blk
+
ACPI_P_LVL3
);
outb
(
inb
(
pm2_cntr
)
&
~
ACPI_ARB_DIS
,
pm2_cntr
);
time
=
inl
(
acpi_facp
->
pm_tmr
)
-
time
;
__sti
();
if
(
time
>
acpi_p_lvl3_lat
||
bm_activity
())
goto
sleep2
;
}
// record working C2/C3
if
(
sleep_level
==
2
&&
!
acpi_p_lvl2_tested
)
{
sleep2:
sleep_level
=
2
;
if
(
!
acpi_p_lvl2_tested
)
{
printk
(
"ACPI C2 works
\n
"
);
acpi_p_lvl2_tested
=
1
;
printk
(
KERN_INFO
"ACPI: C2 works
\n
"
);
}
else
if
(
sleep_level
==
3
&&
!
acpi_p_lvl3_tested
)
{
acpi_p_lvl3_tested
=
1
;
printk
(
KERN_INFO
"ACPI: C3 works
\n
"
);
wake_on_busmaster
();
/* Required to track BM activity.. */
for
(;;)
{
unsigned
long
time
;
__cli
();
if
(
current
->
need_resched
)
goto
out
;
time
=
inl
(
acpi_facp
->
pm_tmr
);
inb
(
acpi_p_blk
+
ACPI_P_LVL2
);
time
=
inl
(
acpi_facp
->
pm_tmr
)
-
time
;
__sti
();
if
(
time
>
acpi_p_lvl2_lat
)
goto
sleep1
;
if
(
bm_activity
())
{
clear_bm_activity
();
continue
;
}
if
(
time
<
acpi_enter_lvl3_lat
)
goto
sleep3
;
}
// pick next C-state based on time spent sleeping,
// C-state latencies, and bus master activity
sleep1:
sleep_level
=
1
;
if
(
acpi_p_blk
)
{
if
(
time
>
acpi_p_lvl3_lat
&&
!
bm_active
)
sleep_level
=
3
;
else
if
(
time
>
acpi_p_lvl2_lat
)
sleep_level
=
2
;
sleep_on_busmaster
();
for
(;;)
{
unsigned
long
time
;
__cli
();
if
(
current
->
need_resched
)
goto
out
;
time
=
inl
(
acpi_facp
->
pm_tmr
);
__asm__
__volatile__
(
"sti ; hlt"
:
:
:
"memory"
);
time
=
inl
(
acpi_facp
->
pm_tmr
)
-
time
;
if
(
time
<
acpi_enter_lvl2_lat
)
goto
sleep2
;
}
not_initialized:
for
(;;)
{
__cli
();
if
(
current
->
need_resched
)
goto
out
;
__asm__
__volatile__
(
"sti ; hlt"
:
:
:
"memory"
);
}
out:
__sti
();
}
/*
...
...
@@ -1119,10 +1177,12 @@ static int __init acpi_init(void)
if
(
acpi_facp
->
p_lvl2_lat
&&
acpi_facp
->
p_lvl2_lat
<=
ACPI_MAX_P_LVL2_LAT
)
{
acpi_p_lvl2_lat
=
acpi_facp
->
p_lvl2_lat
;
acpi_enter_lvl2_lat
=
ACPI_TMR_HZ
/
1000
;
}
if
(
acpi_facp
->
p_lvl3_lat
&&
acpi_facp
->
p_lvl3_lat
<=
ACPI_MAX_P_LVL3_LAT
)
{
acpi_p_lvl3_lat
=
acpi_facp
->
p_lvl3_lat
;
acpi_enter_lvl3_lat
=
acpi_facp
->
p_lvl3_lat
*
5
;
}
if
(
acpi_facp
->
sci_int
...
...
arch/i386/kernel/irq.c
View file @
159f5e24
...
...
@@ -772,6 +772,41 @@ unsigned long probe_irq_on(void)
return
0x12345678
;
}
/*
* Return a mask of triggered interrupts (this
* can handle only legacy ISA interrupts).
*/
unsigned
int
probe_irq_mask
(
unsigned
long
unused
)
{
int
i
;
unsigned
int
mask
;
if
(
unused
!=
0x12345678
)
printk
(
"Bad IRQ probe from %lx
\n
"
,
(
&
unused
)[
-
1
]);
mask
=
0
;
spin_lock_irq
(
&
irq_controller_lock
);
for
(
i
=
0
;
i
<
16
;
i
++
)
{
unsigned
int
status
=
irq_desc
[
i
].
status
;
if
(
!
(
status
&
IRQ_AUTODETECT
))
continue
;
if
(
!
(
status
&
IRQ_WAITING
))
mask
|=
1
<<
i
;
irq_desc
[
i
].
status
=
status
&
~
IRQ_AUTODETECT
;
irq_desc
[
i
].
handler
->
shutdown
(
i
);
}
spin_unlock_irq
(
&
irq_controller_lock
);
return
mask
;
}
/*
* Return the one interrupt that triggered (this can
* handle any interrupt source)
*/
int
probe_irq_off
(
unsigned
long
unused
)
{
int
i
,
irq_found
,
nr_irqs
;
...
...
arch/i386/kernel/setup.c
View file @
159f5e24
...
...
@@ -709,7 +709,7 @@ void __init setup_arch(char **cmdline_p)
#endif
#ifdef CONFIG_BLK_DEV_INITRD
if
(
LOADER_TYPE
)
{
if
(
LOADER_TYPE
&&
INITRD_START
)
{
if
(
INITRD_START
+
INITRD_SIZE
<
(
max_low_pfn
<<
PAGE_SHIFT
))
{
reserve_bootmem
(
INITRD_START
,
INITRD_SIZE
);
initrd_start
=
...
...
drivers/block/rd.c
View file @
159f5e24
...
...
@@ -185,6 +185,8 @@ static void rd_request(request_queue_t * q)
{
unsigned
int
minor
;
unsigned
long
offset
,
len
;
struct
buffer_head
*
rbh
;
struct
buffer_head
*
sbh
;
repeat:
INIT_REQUEST
;
...
...
@@ -211,16 +213,66 @@ static void rd_request(request_queue_t * q)
}
/*
* If we're reading, fill the buffer with 0's. This is okay since
* we're using protected buffers which should never get freed...
* This has become somewhat more complicated with the addition of
* the page cache. The problem is that in some cases the furnished
* buffer is "real", i.e., part of the existing ramdisk, while in
* others it is "unreal", e.g., part of a page. In the first case
* not much needs to be done, while in the second, some kind of
* transfer is needed.
*
* The two cases are distinguished here by checking whether the
* real buffer is already in the buffer cache, and whether it is
* the same as the one supplied.
*
* If we're writing, we protect the buffer.
*/
* There are three cases with read/write to consider:
*
* 1. Supplied buffer matched one in the buffer cache:
* Read - Clear the buffer, as it wasn't already valid.
* Write - Mark the buffer as "Protected".
*
* 2. Supplied buffer mismatched one in the buffer cache:
* Read - Copy the data from the buffer cache entry.
* Write - Copy the data to the buffer cache entry.
*
* 3 No buffer cache entry existed:
* Read - Clear the supplied buffer, but do not create a real
* one.
* Write - Create a real buffer, copy the data to it, and mark
* it as "Protected".
*
* NOTE: There seems to be some schizophrenia here - the logic
* using "len" seems to assume arbitrary request lengths, while
* the "protect" logic assumes a single buffer cache entry.
* This seems to be left over from the ancient contiguous ramdisk
* logic.
*/
if
(
CURRENT
->
cmd
==
READ
)
memset
(
CURRENT
->
buffer
,
0
,
len
);
else
set_bit
(
BH_Protected
,
&
CURRENT
->
bh
->
b_state
);
sbh
=
CURRENT
->
bh
;
rbh
=
get_hash_table
(
sbh
->
b_dev
,
sbh
->
b_blocknr
,
sbh
->
b_size
);
if
(
sbh
==
rbh
)
{
if
(
CURRENT
->
cmd
==
READ
)
memset
(
CURRENT
->
buffer
,
1
,
len
);
}
else
if
(
rbh
)
{
if
(
CURRENT
->
cmd
==
READ
)
memcpy
(
CURRENT
->
buffer
,
rbh
->
b_data
,
rbh
->
b_size
);
else
memcpy
(
rbh
->
b_data
,
CURRENT
->
buffer
,
rbh
->
b_size
);
}
else
{
/* !rbh */
if
(
CURRENT
->
cmd
==
READ
)
memset
(
sbh
->
b_data
,
2
,
len
);
else
{
rbh
=
getblk
(
sbh
->
b_dev
,
sbh
->
b_blocknr
,
sbh
->
b_size
);
if
(
rbh
)
memcpy
(
rbh
->
b_data
,
CURRENT
->
buffer
,
rbh
->
b_size
);
else
BUG
();
/* No buffer, what to do here? */
}
}
if
(
rbh
)
{
set_bit
(
BH_Protected
,
&
rbh
->
b_state
);
brelse
(
rbh
);
}
end_request
(
1
);
goto
repeat
;
...
...
drivers/misc/Config.in
View file @
159f5e24
...
...
@@ -4,6 +4,4 @@
mainmenu_option next_comment
comment 'Misc devices'
bool 'ACPI support' CONFIG_ACPI
endmenu
drivers/misc/Makefile
View file @
159f5e24
...
...
@@ -18,10 +18,6 @@ M_OBJS :=
O_OBJS
:=
OX_OBJS
:=
ifeq
($(CONFIG_ACPI),y)
OX_OBJS
+=
acpi.o
endif
include
$(TOPDIR)/Rules.make
fastdep
:
drivers/net/sis900.c
View file @
159f5e24
/* sis900.c: A SiS 900/7016 PCI Fast Ethernet driver for Linux.
Silicon Integrated System Corporation
Revision: 1.0
5 Aug 7
1999
Copyright 1999
Silicon Integrated System Corporation
Revision: 1.0
6.03 Dec 23
1999
Modified from the driver which is originally written by Donald Becker.
...
...
@@ -18,6 +18,9 @@
preliminary Rev. 1.0 Jan. 18, 1998
http://www.sis.com.tw/support/databook.htm
Rev 1.06.03 Dec. 23 1999 Ollie Lho Third release
Rev 1.06.02 Nov. 23 1999 Ollie Lho bug in mac probing fixed
Rev 1.06.01 Nov. 16 1999 Ollie Lho CRC calculation provide by Joseph Zbiciak (im14u2c@primenet.com)
Rev 1.06 Nov. 4 1999 Ollie Lho (ollie@sis.com.tw) Second release
Rev 1.05.05 Oct. 29 1999 Ollie Lho (ollie@sis.com.tw) Single buffer Tx/Rx
Chin-Shan Li (lcs@sis.com.tw) Added AMD Am79c901 HomePNA PHY support
...
...
@@ -47,7 +50,7 @@
#include "sis900.h"
static
const
char
*
version
=
"sis900.c: v1.06
11/04
/99
\n
"
;
"sis900.c: v1.06
.03 12/23
/99
\n
"
;
static
int
max_interrupt_work
=
20
;
#define sis900_debug debug
...
...
@@ -221,6 +224,8 @@ static struct net_device * sis900_mac_probe (struct mac_chip_info * mac, struct
if
(
did_version
++
==
0
)
printk
(
KERN_INFO
"%s"
,
version
);
if
((
net_dev
=
init_etherdev
(
net_dev
,
0
))
==
NULL
)
return
NULL
;
/* check to see if we have sane EEPROM */
signature
=
(
u16
)
read_eeprom
(
ioaddr
,
EEPROMSignature
);
if
(
signature
==
0xffff
||
signature
==
0x0000
)
{
...
...
@@ -229,9 +234,6 @@ static struct net_device * sis900_mac_probe (struct mac_chip_info * mac, struct
return
NULL
;
}
if
((
net_dev
=
init_etherdev
(
net_dev
,
0
))
==
NULL
)
return
NULL
;
printk
(
KERN_INFO
"%s: %s at %#lx, IRQ %d, "
,
net_dev
->
name
,
mac
->
name
,
ioaddr
,
irq
);
...
...
@@ -509,7 +511,7 @@ sis900_open(struct net_device *net_dev)
net_dev
->
start
=
1
;
/* Enable all known interrupts by setting the interrupt mask. */
outl
((
RxSOVR
|
RxORN
|
RxERR
|
RxOK
|
TxURN
|
TxERR
|
Tx
OK
),
ioaddr
+
imr
);
outl
((
RxSOVR
|
RxORN
|
RxERR
|
RxOK
|
TxURN
|
TxERR
|
Tx
IDLE
),
ioaddr
+
imr
);
outl
(
RxENA
,
ioaddr
+
cr
);
outl
(
IE
,
ioaddr
+
ier
);
...
...
@@ -787,6 +789,7 @@ static void sis900_tx_timeout(struct net_device *net_dev)
{
struct
sis900_private
*
sis_priv
=
(
struct
sis900_private
*
)
net_dev
->
priv
;
long
ioaddr
=
net_dev
->
base_addr
;
int
i
;
printk
(
KERN_INFO
"%s: Transmit timeout, status %8.8x %8.8x
\n
"
,
net_dev
->
name
,
inl
(
ioaddr
+
cr
),
inl
(
ioaddr
+
isr
));
...
...
@@ -794,14 +797,26 @@ static void sis900_tx_timeout(struct net_device *net_dev)
/* Disable interrupts by clearing the interrupt mask. */
outl
(
0x0000
,
ioaddr
+
imr
);
sis_priv
->
cur_rx
=
0
;
/* discard unsent packets, should this code section be protected by
cli(), sti() ?? */
sis_priv
->
dirty_tx
=
sis_priv
->
cur_tx
=
0
;
for
(
i
=
0
;
i
<
NUM_TX_DESC
;
i
++
)
{
if
(
sis_priv
->
tx_skbuff
[
i
]
!=
NULL
)
{
dev_kfree_skb
(
sis_priv
->
tx_skbuff
[
i
]);
sis_priv
->
tx_skbuff
[
i
]
=
0
;
sis_priv
->
tx_ring
[
i
].
cmdsts
=
0
;
sis_priv
->
tx_ring
[
i
].
bufptr
=
0
;
sis_priv
->
stats
.
tx_dropped
++
;
}
}
net_dev
->
trans_start
=
jiffies
;
sis_priv
->
stats
.
tx_errors
++
;
net_dev
->
tbusy
=
sis_priv
->
tx_full
=
0
;
/* FIXME: Should we restart the transmission thread here ?? */
/* Enable all known interrupts by setting the interrupt mask. */
outl
((
RxSOVR
|
RxORN
|
RxERR
|
RxOK
|
TxURN
|
TxERR
|
Tx
OK
),
ioaddr
+
imr
);
outl
((
RxSOVR
|
RxORN
|
RxERR
|
RxOK
|
TxURN
|
TxERR
|
Tx
IDLE
),
ioaddr
+
imr
);
return
;
}
...
...
@@ -876,13 +891,7 @@ static void sis900_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
do
{
status
=
inl
(
ioaddr
+
isr
);
if
(
sis900_debug
>
3
)
printk
(
KERN_INFO
"%s: entering interrupt, "
"original status = %#8.8x, "
"new status = %#8.8x.
\n
"
,
net_dev
->
name
,
status
,
inl
(
ioaddr
+
isr
));
if
((
status
&
(
HIBERR
|
TxURN
|
TxERR
|
TxOK
|
RxORN
|
RxERR
|
RxOK
))
==
0
)
if
((
status
&
(
HIBERR
|
TxURN
|
TxERR
|
TxIDLE
|
RxORN
|
RxERR
|
RxOK
))
==
0
)
/* nothing intresting happened */
break
;
...
...
@@ -891,7 +900,7 @@ static void sis900_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
/* Rx interrupt */
sis900_rx
(
net_dev
);
if
(
status
&
(
TxURN
|
TxERR
|
Tx
OK
))
if
(
status
&
(
TxURN
|
TxERR
|
Tx
IDLE
))
/* Tx interrupt */
sis900_finish_xmit
(
net_dev
);
...
...
@@ -961,6 +970,9 @@ static int sis900_rx(struct net_device *net_dev)
}
else
{
struct
sk_buff
*
skb
;
/* This situation should never happen, but due to
some unknow bugs, it is possible that
we are working on NULL sk_buff :-( */
if
(
sis_priv
->
rx_skbuff
[
entry
]
==
NULL
)
{
printk
(
KERN_INFO
"%s: NULL pointer "
"encountered in Rx ring, skipping
\n
"
,
...
...
@@ -1033,7 +1045,9 @@ static void sis900_finish_xmit (struct net_device *net_dev)
tx_status
=
sis_priv
->
tx_ring
[
entry
].
cmdsts
;
if
(
tx_status
&
OWN
)
{
/* The packet is not transmited yet (owned by hardware) ! */
/* The packet is not transmited yet (owned by hardware) !
Note: the interrupt is generated only when Tx Machine
is idle, so this is an almost impossible case */
break
;
}
...
...
@@ -1054,8 +1068,6 @@ static void sis900_finish_xmit (struct net_device *net_dev)
sis_priv
->
stats
.
tx_window_errors
++
;
}
else
{
/* packet successfully transmited */
if
(
sis900_debug
>
3
)
printk
(
KERN_INFO
"Tx Transmit OK
\n
"
);
sis_priv
->
stats
.
collisions
+=
(
tx_status
&
COLCNT
)
>>
16
;
sis_priv
->
stats
.
tx_bytes
+=
tx_status
&
DSIZE
;
sis_priv
->
stats
.
tx_packets
++
;
...
...
@@ -1069,8 +1081,8 @@ static void sis900_finish_xmit (struct net_device *net_dev)
if
(
sis_priv
->
tx_full
&&
net_dev
->
tbusy
&&
sis_priv
->
cur_tx
-
sis_priv
->
dirty_tx
<
NUM_TX_DESC
-
4
)
{
/* The ring is no longer full, clear tbusy, tx_full and
schedule
more transmission by marking NET_BH */
/* The ring is no longer full, clear tbusy, tx_full and
schedule
more transmission by marking NET_BH */
sis_priv
->
tx_full
=
0
;
clear_bit
(
0
,
(
void
*
)
&
net_dev
->
tbusy
);
mark_bh
(
NET_BH
);
...
...
@@ -1153,11 +1165,13 @@ static u16 sis900_compute_hashtable_index(u8 *addr)
{
/* what is the correct value of the POLYNOMIAL ??
Donald Becker use 0x04C11DB7U */
#define POLYNOMIAL 0x04C11DB6L
Donald Becker use 0x04C11DB7U
Joseph Zbiciak im14u2c@primenet.com gives me the
correct answer, thank you Joe !! */
#define POLYNOMIAL 0x04C11DB7L
u32
crc
=
0xffffffff
,
msb
;
int
i
,
j
;
u
8
byte
;
u
32
byte
;
for
(
i
=
0
;
i
<
6
;
i
++
)
{
byte
=
*
addr
++
;
...
...
@@ -1166,7 +1180,6 @@ static u16 sis900_compute_hashtable_index(u8 *addr)
crc
<<=
1
;
if
(
msb
^
(
byte
&
1
))
{
crc
^=
POLYNOMIAL
;
crc
|=
1
;
}
byte
>>=
1
;
}
...
...
@@ -1208,7 +1221,7 @@ static void set_rx_mode(struct net_device *net_dev)
/* update Multicast Hash Table in Receive Filter */
for
(
i
=
0
;
i
<
8
;
i
++
)
{
/* why plus 0x04 ??, I don't know, UNDOCUMENT FEATURE ??
*/
+
/* why plus 0x04 ??, That makes the correct value for hash table.
*/
outl
((
u32
)(
0x00000004
+
i
)
<<
RFADDR_shift
,
ioaddr
+
rfcr
);
outl
(
mc_filter
[
i
],
ioaddr
+
rfdr
);
}
...
...
drivers/net/sis900.h
View file @
159f5e24
...
...
@@ -92,8 +92,8 @@ enum sis900_transmit_config_register_bits {
/* recevie FIFO thresholds */
#define RxDRNT_shift 1
#define RxDRNT_100
24
/* 3/4
FIFO size */
#define RxDRNT_10
16
/* 1/2
FIFO size */
#define RxDRNT_100
16
/* 1/2
FIFO size */
#define RxDRNT_10
24
/* 3/4
FIFO size */
enum
sis900_reveive_config_register_bits
{
RxAEP
=
0x80000000
,
RxARP
=
0x40000000
,
RxATX
=
0x10000000
,
...
...
drivers/pci/pci.c
View file @
159f5e24
...
...
@@ -413,28 +413,260 @@ void __init pci_read_bridge_bases(struct pci_bus *child)
}
}
static
__init
struct
pci_bus
*
pci_add_new_bus
(
struct
pci_bus
*
parent
,
struct
pci_dev
*
dev
,
int
busnr
)
{
struct
pci_bus
*
child
;
/*
* Allocate a new bus, and inherit stuff from the parent..
*/
child
=
kmalloc
(
sizeof
(
*
child
),
GFP_KERNEL
);
memset
(
child
,
0
,
sizeof
(
*
child
));
child
->
next
=
parent
->
children
;
parent
->
children
=
child
;
child
->
self
=
dev
;
dev
->
subordinate
=
child
;
child
->
parent
=
parent
;
child
->
ops
=
parent
->
ops
;
child
->
sysdata
=
parent
->
sysdata
;
/*
* Set up the primary, secondary and subordinate
* bus numbers. Read resource ranges behind the bridge.
*/
child
->
number
=
child
->
secondary
=
busnr
;
child
->
primary
=
parent
->
secondary
;
child
->
subordinate
=
0xff
;
return
child
;
}
/*
* A CardBus bridge is basically the same as a regular PCI bridge,
* except we don't scan behind it because it will be changing.
*/
static
__init
int
pci_scan_cardbus
(
struct
pci_bus
*
bus
,
struct
pci_dev
*
dev
,
int
busnr
)
{
unsigned
short
cr
;
unsigned
int
buses
;
struct
pci_bus
*
child
;
/*
* Insert it into the tree of buses.
*/
child
=
pci_add_new_bus
(
bus
,
dev
,
++
busnr
);
child
->
subordinate
=
busnr
;
sprintf
(
child
->
name
,
"PCI CardBus #%02x"
,
child
->
number
);
/*
* Clear all status bits and turn off memory,
* I/O and master enables.
*/
pci_read_config_word
(
dev
,
PCI_COMMAND
,
&
cr
);
pci_write_config_word
(
dev
,
PCI_COMMAND
,
0x0000
);
pci_write_config_word
(
dev
,
PCI_STATUS
,
0xffff
);
/*
* Read the existing primary/secondary/subordinate bus
* number configuration to determine if the bridge
* has already been configured by the system. If so,
* do not modify the configuration, merely note it.
*/
pci_read_config_dword
(
dev
,
PCI_PRIMARY_BUS
,
&
buses
);
if
((
buses
&
0xFFFFFF
)
!=
0
&&
!
pcibios_assign_all_busses
())
{
child
->
primary
=
buses
&
0xFF
;
child
->
secondary
=
(
buses
>>
8
)
&
0xFF
;
child
->
subordinate
=
(
buses
>>
16
)
&
0xFF
;
child
->
number
=
child
->
secondary
;
if
(
child
->
subordinate
>
busnr
)
busnr
=
child
->
subordinate
;
}
else
{
/*
* Configure the bus numbers for this bridge:
*/
buses
&=
0xff000000
;
buses
|=
(((
unsigned
int
)(
child
->
primary
)
<<
0
)
|
((
unsigned
int
)(
child
->
secondary
)
<<
8
)
|
((
unsigned
int
)(
child
->
subordinate
)
<<
16
));
pci_write_config_dword
(
dev
,
PCI_PRIMARY_BUS
,
buses
);
}
pci_write_config_word
(
dev
,
PCI_COMMAND
,
cr
);
return
busnr
;
}
static
unsigned
int
__init
pci_do_scan_bus
(
struct
pci_bus
*
bus
);
/*
* If it's a bridge, scan the bus behind it.
*/
static
__init
int
pci_scan_bridge
(
struct
pci_bus
*
bus
,
struct
pci_dev
*
dev
,
int
max
)
{
unsigned
int
buses
;
unsigned
short
cr
;
struct
pci_bus
*
child
;
/*
* Insert it into the tree of buses.
*/
child
=
pci_add_new_bus
(
bus
,
dev
,
++
max
);
sprintf
(
child
->
name
,
"PCI Bus #%02x"
,
child
->
number
);
/*
* Clear all status bits and turn off memory,
* I/O and master enables.
*/
pci_read_config_word
(
dev
,
PCI_COMMAND
,
&
cr
);
pci_write_config_word
(
dev
,
PCI_COMMAND
,
0x0000
);
pci_write_config_word
(
dev
,
PCI_STATUS
,
0xffff
);
/*
* Read the existing primary/secondary/subordinate bus
* number configuration to determine if the PCI bridge
* has already been configured by the system. If so,
* do not modify the configuration, merely note it.
*/
pci_read_config_dword
(
dev
,
PCI_PRIMARY_BUS
,
&
buses
);
if
((
buses
&
0xFFFFFF
)
!=
0
&&
!
pcibios_assign_all_busses
())
{
unsigned
int
cmax
;
child
->
primary
=
buses
&
0xFF
;
child
->
secondary
=
(
buses
>>
8
)
&
0xFF
;
child
->
subordinate
=
(
buses
>>
16
)
&
0xFF
;
child
->
number
=
child
->
secondary
;
cmax
=
pci_do_scan_bus
(
child
);
if
(
cmax
>
max
)
max
=
cmax
;
}
else
{
/*
* Configure the bus numbers for this bridge:
*/
buses
&=
0xff000000
;
buses
|=
(((
unsigned
int
)(
child
->
primary
)
<<
0
)
|
((
unsigned
int
)(
child
->
secondary
)
<<
8
)
|
((
unsigned
int
)(
child
->
subordinate
)
<<
16
));
pci_write_config_dword
(
dev
,
PCI_PRIMARY_BUS
,
buses
);
/*
* Now we can scan all subordinate buses:
*/
max
=
pci_do_scan_bus
(
child
);
/*
* Set the subordinate bus number to its real
* value:
*/
child
->
subordinate
=
max
;
buses
=
(
buses
&
0xff00ffff
)
|
((
unsigned
int
)(
child
->
subordinate
)
<<
16
);
pci_write_config_dword
(
dev
,
PCI_PRIMARY_BUS
,
buses
);
}
pci_write_config_word
(
dev
,
PCI_COMMAND
,
cr
);
return
max
;
}
/*
* Read interrupt line and base address registers.
* The architecture-dependent code can tweak these, of course.
*/
static
__init
void
pci_read_irq
(
struct
pci_dev
*
dev
)
{
unsigned
char
irq
;
pci_read_config_byte
(
dev
,
PCI_INTERRUPT_PIN
,
&
irq
);
if
(
irq
)
pci_read_config_byte
(
dev
,
PCI_INTERRUPT_LINE
,
&
irq
);
dev
->
irq
=
irq
;
}
/*
* Read the config data for a PCI device
* and sanity-check it and fill in the dev
* structure...
*/
static
__init
int
pci_scan_device
(
struct
pci_bus
*
bus
,
struct
pci_dev
*
dev
,
unsigned
int
devfn
)
{
unsigned
int
l
,
class
;
if
(
pci_read_config_dword
(
dev
,
PCI_VENDOR_ID
,
&
l
))
return
-
1
;
/* some broken boards return 0 if a slot is empty: */
if
(
l
==
0xffffffff
||
l
==
0x00000000
||
l
==
0x0000ffff
||
l
==
0xffff0000
)
return
-
1
;
dev
->
vendor
=
l
&
0xffff
;
dev
->
device
=
(
l
>>
16
)
&
0xffff
;
sprintf
(
dev
->
slot_name
,
"%02x:%02x.%d"
,
bus
->
number
,
PCI_SLOT
(
devfn
),
PCI_FUNC
(
devfn
));
pci_name_device
(
dev
);
pci_read_config_dword
(
dev
,
PCI_CLASS_REVISION
,
&
class
);
class
>>=
8
;
/* upper 3 bytes */
dev
->
class
=
class
;
class
>>=
8
;
switch
(
dev
->
hdr_type
)
{
/* header type */
case
PCI_HEADER_TYPE_NORMAL
:
/* standard header */
if
(
class
==
PCI_CLASS_BRIDGE_PCI
)
goto
bad
;
pci_read_irq
(
dev
);
pci_read_bases
(
dev
,
6
,
PCI_ROM_ADDRESS
);
pci_read_config_word
(
dev
,
PCI_SUBSYSTEM_VENDOR_ID
,
&
dev
->
subsystem_vendor
);
pci_read_config_word
(
dev
,
PCI_SUBSYSTEM_ID
,
&
dev
->
subsystem_device
);
break
;
case
PCI_HEADER_TYPE_BRIDGE
:
/* bridge header */
if
(
class
!=
PCI_CLASS_BRIDGE_PCI
)
goto
bad
;
pci_read_bases
(
dev
,
2
,
PCI_ROM_ADDRESS1
);
break
;
case
PCI_HEADER_TYPE_CARDBUS
:
/* CardBus bridge header */
if
(
class
!=
PCI_CLASS_BRIDGE_CARDBUS
)
goto
bad
;
pci_read_irq
(
dev
);
pci_read_bases
(
dev
,
1
,
0
);
pci_read_config_word
(
dev
,
PCI_CB_SUBSYSTEM_VENDOR_ID
,
&
dev
->
subsystem_vendor
);
pci_read_config_word
(
dev
,
PCI_CB_SUBSYSTEM_ID
,
&
dev
->
subsystem_device
);
break
;
default:
/* unknown header */
printk
(
KERN_ERR
"PCI: device %s has unknown header type %02x, ignoring.
\n
"
,
dev
->
slot_name
,
dev
->
hdr_type
);
return
-
1
;
bad:
printk
(
KERN_ERR
"PCI: %s: class %x doesn't match header type %02x. Ignoring class.
\n
"
,
dev
->
slot_name
,
class
,
dev
->
hdr_type
);
dev
->
class
=
PCI_CLASS_NOT_DEFINED
;
}
/* We found a fine healthy device, go go go... */
return
0
;
}
static
unsigned
int
__init
pci_do_scan_bus
(
struct
pci_bus
*
bus
)
{
unsigned
int
devfn
,
l
,
max
,
class
;
unsigned
char
irq
,
hdr_type
,
is_multi
=
0
;
unsigned
int
devfn
,
max
;
struct
pci_dev
*
dev
,
**
bus_last
;
struct
pci_bus
*
child
;
struct
pci_dev
*
dev_cache
=
NULL
;
int
is_multi
=
0
;
DBG
(
"pci_do_scan_bus for bus %d
\n
"
,
bus
->
number
);
bus_last
=
&
bus
->
devices
;
max
=
bus
->
secondary
;
/* Allocate the device ahead of time.. */
dev
=
kmalloc
(
sizeof
(
*
dev
),
GFP_KERNEL
);
if
(
!
dev
)
return
max
;
/* Go find them, Rover! */
for
(
devfn
=
0
;
devfn
<
0xff
;
++
devfn
)
{
if
(
PCI_FUNC
(
devfn
)
&&
!
is_multi
)
{
/* not a multi-function device */
unsigned
char
hdr_type
;
/* not a multi-function device */
if
(
PCI_FUNC
(
devfn
)
&&
!
is_multi
)
continue
;
}
if
(
!
dev_cache
)
{
dev_cache
=
kmalloc
(
sizeof
(
*
dev
),
GFP_KERNEL
);
if
(
!
dev_cache
)
continue
;
}
dev
=
dev_cache
;
memset
(
dev
,
0
,
sizeof
(
*
dev
));
dev
->
bus
=
bus
;
dev
->
sysdata
=
bus
->
sysdata
;
...
...
@@ -442,63 +674,13 @@ static unsigned int __init pci_do_scan_bus(struct pci_bus *bus)
if
(
pci_read_config_byte
(
dev
,
PCI_HEADER_TYPE
,
&
hdr_type
))
continue
;
if
(
!
PCI_FUNC
(
devfn
))
is_multi
=
hdr_type
&
0x80
;
if
(
pci_read_config_dword
(
dev
,
PCI_VENDOR_ID
,
&
l
)
||
/* some broken boards return 0 if a slot is empty: */
l
==
0xffffffff
||
l
==
0x00000000
||
l
==
0x0000ffff
||
l
==
0xffff0000
)
continue
;
dev_cache
=
NULL
;
dev
->
vendor
=
l
&
0xffff
;
dev
->
device
=
(
l
>>
16
)
&
0xffff
;
sprintf
(
dev
->
slot_name
,
"%02x:%02x.%d"
,
bus
->
number
,
PCI_SLOT
(
devfn
),
PCI_FUNC
(
devfn
));
pci_name_device
(
dev
);
pci_read_config_dword
(
dev
,
PCI_CLASS_REVISION
,
&
class
);
class
>>=
8
;
/* upper 3 bytes */
dev
->
class
=
class
;
class
>>=
8
;
dev
->
hdr_type
=
hdr_type
&
0x7f
;
switch
(
dev
->
hdr_type
)
{
/* header type */
case
PCI_HEADER_TYPE_NORMAL
:
/* standard header */
if
(
class
==
PCI_CLASS_BRIDGE_PCI
)
goto
bad
;
/*
* Read interrupt line and base address registers.
* The architecture-dependent code can tweak these, of course.
*/
pci_read_config_byte
(
dev
,
PCI_INTERRUPT_PIN
,
&
irq
);
if
(
irq
)
pci_read_config_byte
(
dev
,
PCI_INTERRUPT_LINE
,
&
irq
);
dev
->
irq
=
irq
;
pci_read_bases
(
dev
,
6
,
PCI_ROM_ADDRESS
);
pci_read_config_word
(
dev
,
PCI_SUBSYSTEM_VENDOR_ID
,
&
dev
->
subsystem_vendor
);
pci_read_config_word
(
dev
,
PCI_SUBSYSTEM_ID
,
&
dev
->
subsystem_device
);
break
;
case
PCI_HEADER_TYPE_BRIDGE
:
/* bridge header */
if
(
class
!=
PCI_CLASS_BRIDGE_PCI
)
goto
bad
;
pci_read_bases
(
dev
,
2
,
PCI_ROM_ADDRESS1
);
break
;
case
PCI_HEADER_TYPE_CARDBUS
:
/* CardBus bridge header */
if
(
class
!=
PCI_CLASS_BRIDGE_CARDBUS
)
goto
bad
;
pci_read_bases
(
dev
,
1
,
0
);
pci_read_config_word
(
dev
,
PCI_CB_SUBSYSTEM_VENDOR_ID
,
&
dev
->
subsystem_vendor
);
pci_read_config_word
(
dev
,
PCI_CB_SUBSYSTEM_ID
,
&
dev
->
subsystem_device
);
break
;
default:
/* unknown header */
printk
(
KERN_ERR
"PCI: device %s has unknown header type %02x, ignoring.
\n
"
,
dev
->
slot_name
,
hdr_type
);
if
(
pci_scan_device
(
bus
,
dev
,
devfn
))
continue
;
bad:
printk
(
KERN_ERR
"PCI: %s: class %x doesn't match header type %02x. Ignoring class.
\n
"
,
dev
->
slot_name
,
class
,
hdr_type
);
dev
->
class
=
PCI_CLASS_NOT_DEFINED
;
}
DBG
(
"PCI: %02x:%02x [%04x/%04x] %06x %02x
\n
"
,
bus
->
number
,
dev
->
devfn
,
dev
->
vendor
,
dev
->
device
,
class
,
hdr_type
);
...
...
@@ -533,95 +715,26 @@ static unsigned int __init pci_do_scan_bus(struct pci_bus *bus)
if (tmp < 32)
pci_write_config_byte(dev, PCI_LATENCY_TIMER, 32);
#endif
dev
=
kmalloc
(
sizeof
(
*
dev
),
GFP_KERNEL
);
}
if
(
dev_cache
)
kfree
(
dev_cache
);
kfree
(
dev
);
/*
* After performing arch-dependent fixup of the bus, look behind
* all PCI-to-PCI bridges on this bus.
*/
pcibios_fixup_bus
(
bus
);
for
(
dev
=
bus
->
devices
;
dev
;
dev
=
dev
->
sibling
)
/*
* If it's a bridge, scan the bus behind it.
*/
if
((
dev
->
class
>>
8
)
==
PCI_CLASS_BRIDGE_PCI
)
{
unsigned
int
buses
;
unsigned
short
cr
;
/*
* Insert it into the tree of buses.
*/
child
=
kmalloc
(
sizeof
(
*
child
),
GFP_KERNEL
);
memset
(
child
,
0
,
sizeof
(
*
child
));
child
->
next
=
bus
->
children
;
bus
->
children
=
child
;
child
->
self
=
dev
;
child
->
parent
=
bus
;
child
->
ops
=
bus
->
ops
;
child
->
sysdata
=
bus
->
sysdata
;
/*
* Set up the primary, secondary and subordinate
* bus numbers. Read resource ranges behind the bridge.
*/
child
->
number
=
child
->
secondary
=
++
max
;
child
->
primary
=
bus
->
secondary
;
child
->
subordinate
=
0xff
;
sprintf
(
child
->
name
,
"PCI Bus #%02x"
,
child
->
number
);
/*
* Clear all status bits and turn off memory,
* I/O and master enables.
*/
pci_read_config_word
(
dev
,
PCI_COMMAND
,
&
cr
);
pci_write_config_word
(
dev
,
PCI_COMMAND
,
0x0000
);
pci_write_config_word
(
dev
,
PCI_STATUS
,
0xffff
);
/*
* Read the existing primary/secondary/subordinate bus
* number configuration to determine if the PCI bridge
* has already been configured by the system. If so,
* do not modify the configuration, merely note it.
*/
pci_read_config_dword
(
dev
,
PCI_PRIMARY_BUS
,
&
buses
);
if
((
buses
&
0xFFFFFF
)
!=
0
&&
!
pcibios_assign_all_busses
())
{
unsigned
int
cmax
;
child
->
primary
=
buses
&
0xFF
;
child
->
secondary
=
(
buses
>>
8
)
&
0xFF
;
child
->
subordinate
=
(
buses
>>
16
)
&
0xFF
;
child
->
number
=
child
->
secondary
;
cmax
=
pci_do_scan_bus
(
child
);
if
(
cmax
>
max
)
max
=
cmax
;
}
else
{
/*
* Configure the bus numbers for this bridge:
*/
buses
&=
0xff000000
;
buses
|=
(((
unsigned
int
)(
child
->
primary
)
<<
0
)
|
((
unsigned
int
)(
child
->
secondary
)
<<
8
)
|
((
unsigned
int
)(
child
->
subordinate
)
<<
16
));
pci_write_config_dword
(
dev
,
PCI_PRIMARY_BUS
,
buses
);
/*
* Now we can scan all subordinate buses:
*/
max
=
pci_do_scan_bus
(
child
);
/*
* Set the subordinate bus number to its real
* value:
*/
child
->
subordinate
=
max
;
buses
=
(
buses
&
0xff00ffff
)
|
((
unsigned
int
)(
child
->
subordinate
)
<<
16
);
pci_write_config_dword
(
dev
,
PCI_PRIMARY_BUS
,
buses
);
}
pci_write_config_word
(
dev
,
PCI_COMMAND
,
cr
);
for
(
dev
=
bus
->
devices
;
dev
;
dev
=
dev
->
sibling
)
{
switch
(
dev
->
class
>>
8
)
{
case
PCI_CLASS_BRIDGE_PCI
:
max
=
pci_scan_bridge
(
bus
,
dev
,
max
);
break
;
case
PCI_CLASS_BRIDGE_CARDBUS
:
max
=
pci_scan_cardbus
(
bus
,
dev
,
max
);
break
;
}
}
/*
* We've scanned the bus and so we know all about what's on
...
...
drivers/pcmcia/pci_socket.h
View file @
159f5e24
...
...
@@ -8,11 +8,12 @@ struct pci_socket_ops;
typedef
struct
pci_socket
{
struct
pci_dev
*
dev
;
int
irq
;
int
cb_irq
,
io_
irq
;
void
*
base
;
void
(
*
handler
)(
void
*
,
unsigned
int
);
void
*
info
;
struct
pci_socket_ops
*
op
;
socket_cap_t
cap
;
}
pci_socket_t
;
struct
pci_socket_ops
{
...
...
drivers/pcmcia/yenta.c
View file @
159f5e24
...
...
@@ -7,6 +7,7 @@
#include <linux/pci.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <pcmcia/ss.h>
...
...
@@ -19,19 +20,9 @@
#define to_cycles(ns) ((ns)/120)
#define to_ns(cycles) ((cycles)*120)
/* Fixme! */
static
int
yenta_inquire
(
pci_socket_t
*
socket
,
socket_cap_t
*
cap
)
{
cap
->
features
=
SS_CAP_PAGE_REGS
|
SS_CAP_PCCARD
|
SS_CAP_CARDBUS
;
cap
->
irq_mask
=
0xdeb8
;
/* irq 15,14,12,11,10,9,7,5,4,3 */
cap
->
map_size
=
0x1000
;
cap
->
pci_irq
=
socket
->
irq
;
cap
->
cardbus
=
0
;
cap
->
cb_bus
=
NULL
;
cap
->
bus
=
NULL
;
printk
(
"yenta_inquire()
\n
"
);
*
cap
=
socket
->
cap
;
return
0
;
}
...
...
@@ -92,7 +83,7 @@ static int yenta_get_socket(pci_socket_t *socket, socket_state_t *state)
state
->
Vcc
=
yenta_Vcc_power
(
control
);
state
->
Vpp
=
yenta_Vpp_power
(
control
);
state
->
io_irq
=
socket
->
irq
;
state
->
io_irq
=
socket
->
i
o_i
rq
;
reg
=
exca_readb
(
socket
,
I365_POWER
);
state
->
flags
=
(
reg
&
I365_PWR_AUTO
)
?
SS_PWR_AUTO
:
0
;
...
...
@@ -129,14 +120,37 @@ printk("yenta_set_socket(%p, %d, %d, %x)\n", socket, state->Vcc, state->Vpp, sta
bridge
&=
~
CB_BRIDGE_CRST
;
bridge
|=
(
state
->
flags
&
SS_RESET
)
?
CB_BRIDGE_CRST
:
0
;
config_writew
(
socket
,
CB_BRIDGE_CONTROL
,
bridge
);
reg
=
socket
->
irq
;
/* Set the IO interrupt and socket state */
reg
=
state
->
io_irq
;
reg
|=
(
state
->
flags
&
SS_RESET
)
?
0
:
I365_PC_RESET
;
reg
|=
(
state
->
flags
&
SS_IOCARD
)
?
I365_PC_IOCARD
:
0
;
exca_writeb
(
socket
,
I365_INTCTL
,
reg
);
/* Set host interrupt and CSC mask state */
reg
=
socket
->
cb_irq
<<
4
;
reg
|=
(
state
->
csc_mask
&
SS_DETECT
)
?
I365_CSC_DETECT
:
0
;
if
(
state
->
flags
&
SS_IOCARD
)
{
reg
|=
(
state
->
csc_mask
&
SS_STSCHG
)
?
I365_CSC_STSCHG
:
0
;
}
else
{
reg
|=
(
state
->
csc_mask
&
SS_BATDEAD
)
?
I365_CSC_BVD1
:
0
;
reg
|=
(
state
->
csc_mask
&
SS_BATWARN
)
?
I365_CSC_BVD2
:
0
;
reg
|=
(
state
->
csc_mask
&
SS_READY
)
?
I365_CSC_READY
:
0
;
}
exca_writeb
(
socket
,
I365_CSCINT
,
reg
);
exca_readb
(
socket
,
I365_CSC
);
/*
* Set power state..
*
* I wonder if we could do the Vcc/Vpp part through the
* CB interface only..
*/
reg
=
I365_PWR_NORESET
;
control
=
0
;
/* CB_STOPCLK ? Better power management */
reg
|=
(
state
->
flags
&
SS_PWR_AUTO
)
?
I365_PWR_AUTO
:
0
;
reg
|=
(
state
->
flags
&
SS_OUTPUT_ENA
)
?
I365_PWR_OUT
:
0
;
control
=
CB_STOPCLK
;
switch
(
state
->
Vcc
)
{
case
33
:
control
|=
CB_PWR3V
<<
CB_VCCCTRL
;
...
...
@@ -161,24 +175,8 @@ printk("yenta_set_socket(%p, %d, %d, %x)\n", socket, state->Vcc, state->Vpp, sta
reg
|=
I365_VPP1_12V
;
break
;
}
cb_writel
(
socket
,
CB_SOCKET_CONTROL
,
control
);
reg
|=
(
state
->
flags
&
SS_PWR_AUTO
)
?
I365_PWR_AUTO
:
0
;
reg
|=
(
state
->
flags
&
SS_OUTPUT_ENA
)
?
I365_PWR_OUT
:
0
;
if
(
state
->
flags
&
SS_PWR_AUTO
)
reg
|=
I365_PWR_AUTO
;
exca_writeb
(
socket
,
I365_POWER
,
reg
);
reg
=
socket
->
irq
;
reg
|=
(
state
->
csc_mask
&
SS_DETECT
)
?
I365_CSC_DETECT
:
0
;
if
(
state
->
flags
&
SS_IOCARD
)
{
reg
|=
(
state
->
csc_mask
&
SS_STSCHG
)
?
I365_CSC_STSCHG
:
0
;
}
else
{
reg
|=
(
state
->
csc_mask
&
SS_BATDEAD
)
?
I365_CSC_BVD1
:
0
;
reg
|=
(
state
->
csc_mask
&
SS_BATWARN
)
?
I365_CSC_BVD2
:
0
;
reg
|=
(
state
->
csc_mask
&
SS_READY
)
?
I365_CSC_READY
:
0
;
}
exca_writeb
(
socket
,
I365_CSCINT
,
reg
);
exca_readb
(
socket
,
I365_CSC
);
cb_writel
(
socket
,
CB_SOCKET_CONTROL
,
control
);
return
0
;
}
...
...
@@ -329,6 +327,8 @@ printk("yenta_set_map(%d, %x, %x, %x)\n", map, start, stop, card_start);
word
|=
I365_MEM_REG
;
exca_writew
(
socket
,
I365_MEM
(
map
)
+
I365_W_OFF
,
word
);
exca_writeb
(
socket
,
CB_MEM_PAGE
(
map
),
start
>>
24
);
if
(
mem
->
flags
&
MAP_ACTIVE
)
exca_writeb
(
socket
,
I365_ADDRWIN
,
addr
|
enable
);
return
0
;
...
...
@@ -336,14 +336,65 @@ printk("yenta_set_map(%d, %x, %x, %x)\n", map, start, stop, card_start);
static
int
yenta_get_bridge
(
pci_socket_t
*
socket
,
struct
cb_bridge_map
*
m
)
{
printk
(
"yenta_get_bridge() called
\n
"
);
return
-
EINVAL
;
unsigned
map
;
map
=
m
->
map
;
if
(
map
>
1
)
return
-
EINVAL
;
m
->
flags
&=
MAP_IOSPACE
;
map
+=
(
m
->
flags
&
MAP_IOSPACE
)
?
2
:
0
;
m
->
start
=
config_readl
(
socket
,
CB_BRIDGE_BASE
(
map
));
m
->
stop
=
config_readl
(
socket
,
CB_BRIDGE_LIMIT
(
map
));
if
(
m
->
start
||
m
->
stop
)
{
m
->
flags
|=
MAP_ACTIVE
;
m
->
stop
|=
(
map
>
1
)
?
3
:
0x0fff
;
}
/* Get prefetch state for memory mappings */
if
(
map
<
2
)
{
u16
ctrl
,
prefetch_mask
=
CB_BRIDGE_PREFETCH0
<<
map
;
ctrl
=
config_readw
(
socket
,
CB_BRIDGE_CONTROL
);
m
->
flags
|=
(
ctrl
&
prefetch_mask
)
?
MAP_PREFETCH
:
0
;
}
return
0
;
}
static
int
yenta_set_bridge
(
pci_socket_t
*
socket
,
struct
cb_bridge_map
*
m
)
{
printk
(
"yenta_set_bridge() called
\n
"
);
return
-
EINVAL
;
unsigned
map
;
u32
start
,
end
;
map
=
m
->
map
;
if
(
map
>
1
||
m
->
stop
<
m
->
start
)
return
-
EINVAL
;
if
(
m
->
flags
&
MAP_IOSPACE
)
{
if
((
m
->
stop
>
0xffff
)
||
(
m
->
start
&
3
)
||
((
m
->
stop
&
3
)
!=
3
))
return
-
EINVAL
;
map
+=
2
;
}
else
{
u16
ctrl
,
prefetch_mask
=
CB_BRIDGE_PREFETCH0
<<
map
;
if
((
m
->
start
&
0x0fff
)
||
((
m
->
stop
&
0x0fff
)
!=
0x0fff
))
return
-
EINVAL
;
ctrl
=
config_readw
(
socket
,
CB_BRIDGE_CONTROL
);
ctrl
&=
~
prefetch_mask
;
ctrl
|=
(
m
->
flags
&
MAP_PREFETCH
)
?
prefetch_mask
:
0
;
config_writew
(
socket
,
CB_BRIDGE_CONTROL
,
ctrl
);
}
start
=
0
;
end
=
0
;
if
(
m
->
flags
&
MAP_ACTIVE
)
{
start
=
m
->
start
;
end
=
m
->
stop
;
}
config_writel
(
socket
,
CB_BRIDGE_BASE
(
map
),
start
);
config_writel
(
socket
,
CB_BRIDGE_LIMIT
(
map
),
end
);
return
0
;
}
static
void
yenta_proc_setup
(
pci_socket_t
*
socket
,
struct
proc_dir_entry
*
base
)
...
...
@@ -380,6 +431,39 @@ static void yenta_interrupt(int irq, void *dev_id, struct pt_regs *regs)
socket
->
handler
(
socket
->
info
,
events
);
}
static
unsigned
int
yenta_probe_irq
(
pci_socket_t
*
socket
)
{
int
i
;
unsigned
long
val
;
cb_writel
(
socket
,
CB_SOCKET_EVENT
,
-
1
);
cb_writel
(
socket
,
CB_SOCKET_MASK
,
CB_CSTSMASK
);
val
=
probe_irq_on
();
for
(
i
=
1
;
i
<
16
;
i
++
)
{
exca_writeb
(
socket
,
I365_CSCINT
,
I365_CSC_STSCHG
|
(
i
<<
4
));
cb_writel
(
socket
,
CB_SOCKET_FORCE
,
CB_FCARDSTS
);
udelay
(
100
);
cb_writel
(
socket
,
CB_SOCKET_EVENT
,
-
1
);
}
cb_writel
(
socket
,
CB_SOCKET_MASK
,
0
);
return
probe_irq_mask
(
val
);
}
static
void
yenta_get_socket_capabilities
(
pci_socket_t
*
socket
)
{
socket
->
cap
.
features
=
SS_CAP_PAGE_REGS
|
SS_CAP_PCCARD
|
SS_CAP_CARDBUS
;
socket
->
cap
.
irq_mask
=
yenta_probe_irq
(
socket
);
if
(
socket
->
cb_irq
&&
socket
->
cb_irq
<
16
)
socket
->
cap
.
irq_mask
|=
1
<<
socket
->
cb_irq
;
socket
->
cap
.
map_size
=
0x1000
;
socket
->
cap
.
pci_irq
=
socket
->
cb_irq
;
socket
->
cap
.
cardbus
=
config_readb
(
socket
,
PCI_CB_CARD_BUS
);
socket
->
cap
.
cb_bus
=
socket
->
dev
->
subordinate
;
socket
->
cap
.
bus
=
NULL
;
printk
(
"Yenta IRQ list %04x
\n
"
,
socket
->
cap
.
irq_mask
);
}
/*
* Initialize a cardbus controller. Make sure we have a usable
* interrupt, and that we can map the cardbus area. Fill in the
...
...
@@ -396,10 +480,6 @@ static int yenta_open(pci_socket_t *socket)
printk
(
"Unable to enable device
\n
"
);
return
-
1
;
}
if
(
!
dev
->
irq
)
{
printk
(
"No cardbus irq!
\n
"
);
return
-
1
;
}
if
(
!
dev
->
resource
[
0
].
start
)
{
printk
(
"No cardbus resource!
\n
"
);
return
-
1
;
...
...
@@ -412,9 +492,12 @@ static int yenta_open(pci_socket_t *socket)
socket
->
base
=
ioremap
(
dev
->
resource
[
0
].
start
,
0x1000
);
if
(
!
socket
->
base
)
return
-
1
;
if
(
request_irq
(
dev
->
irq
,
yenta_interrupt
,
SA_SHIRQ
,
dev
->
name
,
socket
))
return
-
1
;
socket
->
irq
=
dev
->
irq
;
if
(
dev
->
irq
&&
!
request_irq
(
dev
->
irq
,
yenta_interrupt
,
SA_SHIRQ
,
dev
->
name
,
socket
))
socket
->
cb_irq
=
dev
->
irq
;
/* Figure out what the dang thing can do.. */
yenta_get_socket_capabilities
(
socket
);
/* Enable all events */
writel
(
0x0f
,
socket
->
base
+
4
);
...
...
@@ -428,8 +511,8 @@ static int yenta_open(pci_socket_t *socket)
*/
static
void
yenta_close
(
pci_socket_t
*
sock
)
{
if
(
sock
->
irq
)
free_irq
(
sock
->
irq
,
sock
);
if
(
sock
->
cb_
irq
)
free_irq
(
sock
->
cb_
irq
,
sock
);
if
(
sock
->
base
)
iounmap
(
sock
->
base
);
}
...
...
drivers/pcmcia/yenta.h
View file @
159f5e24
...
...
@@ -102,6 +102,8 @@
/*
* Cardbus configuration space
*/
#define CB_BRIDGE_BASE(m) (0x1c + 8*(m))
#define CB_BRIDGE_LIMIT(m) (0x20 + 8*(m))
#define CB_BRIDGE_CONTROL 0x3e
#define CB_BRIDGE_CPERREN 0x00000001
#define CB_BRIDGE_CSERREN 0x00000002
...
...
drivers/scsi/scsi_lib.c
View file @
159f5e24
...
...
@@ -821,12 +821,14 @@ void scsi_request_fn(request_queue_t * q)
* get those allocated here.
*/
if
(
!
SDpnt
->
scsi_init_io_fn
(
SCpnt
))
{
spin_lock_irq
(
&
io_request_lock
);
continue
;
}
/*
* Initialize the actual SCSI command for this request.
*/
if
(
!
STpnt
->
init_command
(
SCpnt
))
{
spin_lock_irq
(
&
io_request_lock
);
continue
;
}
}
...
...
drivers/usb/acm.c
View file @
159f5e24
/*
* USB Abstract Control Model based on Brad Keryan's USB busmouse driver
*
* (C) Copyright 1999 Armin Fuerst <
armin.please@put.your.email.here.!!!!
>
* (C) Copyright 1999 Armin Fuerst <
fuerst@in.tum.de
>
* (C) Copyright 1999 Pavel Machek <pavel@suse.cz>
* (C) Copyright 1999 Johannes Erdfelt <jerdfelt@valinux.com>
*
* version 0.9: Johanness Erdfelt converted this to urb interface.
*
* version 0.8: Fixed endianity bug, some cleanups. I really hate to have
* half of driver in form if (...) { info("x"); return y; }
* Pavel Machek <pavel@suse.cz>
...
...
@@ -92,13 +94,12 @@ struct acm_state {
char
active
;
//someone has this acm's device open
unsigned
int
ctrlstate
;
//Status of the serial control lines (handshake,...)
unsigned
int
linecoding
;
//Status of the line coding (Bits, Stop, Parity)
int
writesize
,
readsize
;
//size of the usb buffers
char
*
writebuffer
,
*
readbuffer
;
//the usb buffers
void
*
readtransfer
,
*
writetransfer
;
void
*
ctrltransfer
;
//ptr to HC internal transfer struct
int
writesize
,
readsize
,
ctrlsize
;
//size of the usb buffers
char
*
writebuffer
,
*
readbuffer
,
*
ctrlbuffer
;
//the usb buffers
char
writing
,
reading
;
//flag if transfer is running
unsigned
int
readendp
,
writeendp
,
ctrlendp
;
//endpoints and
unsigned
int
readpipe
,
writepipe
,
ctrlpipe
;
//pipes (are one of these obsolete?)
urb_t
*
readurb
,
*
writeurb
,
*
ctrlurb
;
unsigned
ctrlinterval
;
//interval to poll from device
};
...
...
@@ -135,31 +136,30 @@ void Set_Line_Coding(unsigned int coding, struct acm_state *acm)
}
//Interrupt handler for various usb events
static
int
acm_irq
(
int
state
,
void
*
__buffer
,
int
count
,
void
*
dev_id
)
static
void
acm_irq
(
urb_t
*
urb
)
{
unsigned
char
*
data
;
struct
acm_state
*
acm
=
(
struct
acm_state
*
)
dev_id
;
devrequest
*
dr
;
struct
acm_state
*
acm
=
(
struct
acm_state
*
)
urb
->
context
;
unsigned
char
*
data
=
urb
->
transfer_buffer
;
devrequest
*
dr
;
info
(
"ACM_USB_IRQ
\n
"
);
if
(
state
)
{
printk
(
KERN_DEBUG
"acm_irq: strange stat
e received: %x
\n
"
,
state
);
return
0
;
if
(
urb
->
status
<
0
)
{
printk
(
KERN_DEBUG
"acm_irq: strange stat
us received: %d
\n
"
,
urb
->
status
);
return
;
}
if
(
!
acm
->
present
)
return
0
;
return
;
if
(
!
acm
->
active
)
return
1
;
return
;
dr
=
__buffer
;
data
=
__buffer
;
dr
=
(
devrequest
*
)
data
;
data
+=
sizeof
(
dr
);
#if 0
printk("reqtype: %02X\n",dr->requesttype);
printk("request: %02X\n",dr->request);
printk("reqtype: %02X\n",dr->requesttype);
printk("request: %02X\n",dr->request);
printk("wValue: %02X\n",dr->value);
printk("wIndex: %02X\n",dr->index);
printk("wLength: %02X\n",dr->length);
...
...
@@ -179,55 +179,56 @@ static int acm_irq(int state, void *__buffer, int count, void *dev_id)
case
0x20
:
/* Set serial line state */
printk
(
KERN_DEBUG
"acm.c: Set serial control line state
\n
"
);
if
((
dr
->
index
==
1
)
&&
(
dr
->
length
==
2
))
{
acm
->
ctrlstate
=
data
[
0
]
||
(
data
[
1
]
<<
16
);
printk
(
KERN_DEBUG
"Serstate: %02X
\n
"
,
acm
->
ctrlstate
);
acm
->
ctrlstate
=
data
[
0
]
||
(
data
[
1
]
<<
16
);
printk
(
KERN_DEBUG
"Serstate: %02X
\n
"
,
acm
->
ctrlstate
);
}
break
;
}
return
1
;
/* Continue transfer */
return
;
}
static
int
acm_read_irq
(
int
state
,
void
*
__buffer
,
int
count
,
void
*
dev_id
)
static
void
acm_read_irq
(
urb_t
*
urb
)
{
struct
acm_state
*
acm
=
(
struct
acm_state
*
)
dev_id
;
struct
acm_state
*
acm
=
(
struct
acm_state
*
)
urb
->
context
;
struct
tty_struct
*
tty
=
acm
->
tty
;
unsigned
char
*
data
=
__
buffer
;
unsigned
char
*
data
=
acm
->
read
buffer
;
int
i
;
info
(
"ACM_READ_IRQ: state %d, %d bytes
\n
"
,
state
,
count
);
if
(
state
)
{
printk
(
"acm_read_irq: strange state received: %x
\n
"
,
state
);
return
1
;
info
(
"ACM_READ_IRQ: state %d, %d bytes
\n
"
,
urb
->
status
,
urb
->
actual_length
);
if
(
urb
->
status
)
{
printk
(
"acm_read_irq: strange state received: %d
\n
"
,
urb
->
status
);
return
;
}
if
(
!
ACM_READY
)
return
0
;
/* stop transfer */
return
;
for
(
i
=
0
;
i
<
count
;
i
++
)
for
(
i
=
0
;
i
<
urb
->
actual_length
;
i
++
)
tty_insert_flip_char
(
tty
,
data
[
i
],
0
);
tty_flip_buffer_push
(
tty
);
return
1
;
usb_submit_urb
(
urb
);
return
;
}
static
int
acm_write_irq
(
int
state
,
void
*
__buffer
,
int
count
,
void
*
dev_id
)
static
void
acm_write_irq
(
urb_t
*
urb
)
{
struct
acm_state
*
acm
=
(
struct
acm_state
*
)
dev_id
;
struct
acm_state
*
acm
=
(
struct
acm_state
*
)
urb
->
context
;
struct
tty_struct
*
tty
=
acm
->
tty
;
info
(
"ACM_WRITE_IRQ
\n
"
);
if
(
!
ACM_READY
)
return
0
;
/* stop transfer */
return
;
usb_terminate_bulk
(
acm
->
dev
,
acm
->
writetransfer
);
acm
->
writing
=
0
;
if
((
tty
->
flags
&
(
1
<<
TTY_DO_WRITE_WAKEUP
))
&&
tty
->
ldisc
.
write_wakeup
)
(
tty
->
ldisc
.
write_wakeup
)(
tty
);
wake_up_interruptible
(
&
tty
->
write_wait
);
return
0
;
/* stop tranfer */
return
;
}
/*TTY STUFF*/
...
...
@@ -251,13 +252,21 @@ static int rs_open(struct tty_struct *tty, struct file *filp)
MOD_INC_USE_COUNT
;
/* Start reading from the device */
ret
=
usb_request_irq
(
acm
->
dev
,
acm
->
ctrlpipe
,
acm_irq
,
acm
->
ctrlinterval
,
acm
,
&
acm
->
ctrltransfer
);
FILL_INT_URB
(
acm
->
ctrlurb
,
acm
->
dev
,
acm
->
ctrlpipe
,
acm
->
ctrlbuffer
,
acm
->
ctrlsize
,
acm_irq
,
acm
,
acm
->
ctrlinterval
);
ret
=
usb_submit_urb
(
acm
->
ctrlurb
);
if
(
ret
)
printk
(
KERN_ERR
"usb-acm: usb_request_irq failed (0x%x)
\n
"
,
ret
);
printk
(
KERN_ERR
"acm: usb_submit_urb(INT) failed (%d)
\n
"
,
ret
);
acm
->
reading
=
1
;
FILL_BULK_URB
(
acm
->
readurb
,
acm
->
dev
,
acm
->
readpipe
,
acm
->
readbuffer
,
acm
->
readsize
,
acm_read_irq
,
acm
);
ret
=
usb_submit_urb
(
acm
->
readurb
);
if
(
ret
)
printk
(
KERN_ERR
"acm: usb_submit_urb(READ) failed (%d)
\n
"
,
ret
);
acm
->
reading
=
1
;
acm
->
readtransfer
=
usb_request_bulk
(
acm
->
dev
,
acm
->
readpipe
,
acm_read_irq
,
acm
->
readbuffer
,
acm
->
readsize
,
acm
);
Set_Control_Line_Status
(
CTRL_STAT_DTR
|
CTRL_STAT_RTS
,
acm
);
...
...
@@ -266,7 +275,7 @@ static int rs_open(struct tty_struct *tty, struct file *filp)
static
void
rs_close
(
struct
tty_struct
*
tty
,
struct
file
*
filp
)
{
struct
acm_state
*
acm
=
(
struct
acm_state
*
)
tty
->
driver_data
;
struct
acm_state
*
acm
=
(
struct
acm_state
*
)
tty
->
driver_data
;
info
(
"rs_close
\n
"
);
...
...
@@ -274,20 +283,22 @@ static void rs_close(struct tty_struct *tty, struct file *filp)
return
;
if
(
--
acm
->
active
)
return
;
goto
early
;
Set_Control_Line_Status
(
0
,
acm
);
if
(
acm
->
writing
)
{
usb_terminate_bulk
(
acm
->
dev
,
acm
->
writetransfer
);
if
(
acm
->
writeurb
)
usb_unlink_urb
(
acm
->
writeurb
);
acm
->
writing
=
0
;
}
if
(
acm
->
reading
)
{
usb_terminate_bulk
(
acm
->
dev
,
acm
->
readtransfer
);
if
(
acm
->
readurb
)
usb_unlink_urb
(
acm
->
readurb
);
acm
->
reading
=
0
;
}
// usb_release_irq(acm->dev, acm->ctrltransfer, acm->ctrlpipe);
early:
MOD_DEC_USE_COUNT
;
}
...
...
@@ -295,7 +306,7 @@ static int rs_write(struct tty_struct *tty, int from_user,
const
unsigned
char
*
buf
,
int
count
)
{
struct
acm_state
*
acm
=
(
struct
acm_state
*
)
tty
->
driver_data
;
int
written
;
int
written
,
ret
;
info
(
"rs_write
\n
"
);
...
...
@@ -316,8 +327,12 @@ static int rs_write(struct tty_struct *tty, int from_user,
//start the transfer
acm
->
writing
=
1
;
acm
->
writetransfer
=
usb_request_bulk
(
acm
->
dev
,
acm
->
writepipe
,
acm_write_irq
,
acm
->
writebuffer
,
written
,
acm
);
FILL_BULK_URB
(
acm
->
writeurb
,
acm
->
dev
,
acm
->
writepipe
,
acm
->
writebuffer
,
written
,
acm_write_irq
,
acm
);
ret
=
usb_submit_urb
(
acm
->
writeurb
);
if
(
ret
)
printk
(
"acm: usb_submit_urb(WRITE) failed: %d
\n
"
,
ret
);
return
written
;
}
...
...
@@ -330,7 +345,7 @@ static void rs_put_char(struct tty_struct *tty, unsigned char ch)
static
int
rs_write_room
(
struct
tty_struct
*
tty
)
{
struct
acm_state
*
acm
=
(
struct
acm_state
*
)
tty
->
driver_data
;
struct
acm_state
*
acm
=
(
struct
acm_state
*
)
tty
->
driver_data
;
info
(
"rs_write_room
\n
"
);
...
...
@@ -342,7 +357,7 @@ static int rs_write_room(struct tty_struct *tty)
static
int
rs_chars_in_buffer
(
struct
tty_struct
*
tty
)
{
struct
acm_state
*
acm
=
(
struct
acm_state
*
)
tty
->
driver_data
;
struct
acm_state
*
acm
=
(
struct
acm_state
*
)
tty
->
driver_data
;
// info("rs_chars_in_buffer\n");
...
...
@@ -354,7 +369,7 @@ static int rs_chars_in_buffer(struct tty_struct *tty)
static
void
rs_throttle
(
struct
tty_struct
*
tty
)
{
struct
acm_state
*
acm
=
(
struct
acm_state
*
)
tty
->
driver_data
;
struct
acm_state
*
acm
=
(
struct
acm_state
*
)
tty
->
driver_data
;
info
(
"rs_throttle
\n
"
);
...
...
@@ -414,7 +429,7 @@ static void * acm_probe(struct usb_device *dev, unsigned int ifnum)
/* Only use CDC */
if
(
dev
->
descriptor
.
bDeviceClass
!=
2
||
dev
->
descriptor
.
bDeviceSubClass
!=
0
||
dev
->
descriptor
.
bDeviceProtocol
!=
0
)
dev
->
descriptor
.
bDeviceProtocol
!=
0
)
return
NULL
;
#define IFCLASS(if) ((if->bInterfaceClass << 24) | (if->bInterfaceSubClass << 16) | (if->bInterfaceProtocol << 8) | (if->bNumEndpoints))
...
...
@@ -423,6 +438,8 @@ static void * acm_probe(struct usb_device *dev, unsigned int ifnum)
* selecting or should the usbcore? [different configurations
* can have different bandwidth requirements] -greg */
printk
(
"Acm: found device with right class...
\n
"
);
/* Now scan all configs for a ACM configuration */
for
(
cfgnum
=
0
;
cfgnum
<
dev
->
descriptor
.
bNumConfigurations
;
cfgnum
++
)
{
/* The first one should be Communications interface? */
...
...
@@ -465,7 +482,7 @@ static void * acm_probe(struct usb_device *dev, unsigned int ifnum)
(
endpoint
->
bmAttributes
&
3
)
!=
2
)
continue
;
printk
(
"USB ACM %d found
\n
"
,
acmno
);
printk
(
"USB ACM %d found
on config %d
\n
"
,
acmno
,
cfgnum
);
usb_set_configuration
(
dev
,
dev
->
config
[
cfgnum
].
bConfigurationValue
);
acm
->
dev
=
dev
;
...
...
@@ -478,6 +495,11 @@ static void * acm_probe(struct usb_device *dev, unsigned int ifnum)
printk
(
"ACM: Couldn't allocate readbuffer
\n
"
);
return
NULL
;
}
acm
->
readurb
=
usb_alloc_urb
(
0
);
if
(
!
acm
->
readurb
)
{
printk
(
"acm: couldn't allocate read urb
\n
"
);
return
NULL
;
}
acm
->
writeendp
=
dev
->
config
[
cfgnum
].
interface
[
1
].
altsetting
[
0
].
endpoint
[
1
^
swapped
].
bEndpointAddress
;
acm
->
writepipe
=
usb_sndbulkpipe
(
dev
,
acm
->
writeendp
);
...
...
@@ -488,10 +510,25 @@ static void * acm_probe(struct usb_device *dev, unsigned int ifnum)
kfree
(
acm
->
readbuffer
);
return
NULL
;
}
acm
->
writeurb
=
usb_alloc_urb
(
0
);
if
(
!
acm
->
writeurb
)
{
printk
(
"acm: couldn't allocate write urb
\n
"
);
return
NULL
;
}
acm
->
ctrlbuffer
=
kmalloc
(
acm
->
ctrlsize
=
dev
->
config
[
cfgnum
].
interface
[
0
].
altsetting
[
0
].
endpoint
[
0
].
wMaxPacketSize
,
GFP_KERNEL
);
acm
->
ctrlendp
=
dev
->
config
[
cfgnum
].
interface
[
0
].
altsetting
[
0
].
endpoint
[
0
].
bEndpointAddress
;
acm
->
ctrlpipe
=
usb_rcv
ctrl
pipe
(
acm
->
dev
,
acm
->
ctrlendp
);
acm
->
ctrlpipe
=
usb_rcv
int
pipe
(
acm
->
dev
,
acm
->
ctrlendp
);
acm
->
ctrlinterval
=
dev
->
config
[
cfgnum
].
interface
[
0
].
altsetting
[
0
].
endpoint
[
0
].
bInterval
;
if
(
!
acm
->
ctrlbuffer
)
{
printk
(
"acm: couldn't allocate ctrlbuffer
\n
"
);
return
NULL
;
}
acm
->
ctrlurb
=
usb_alloc_urb
(
0
);
if
(
!
acm
->
ctrlurb
)
{
printk
(
"acm: couldn't allocate write urb
\n
"
);
return
NULL
;
}
acm
->
cfgnum
=
cfgnum
;
acm
->
present
=
1
;
...
...
@@ -517,18 +554,30 @@ static void acm_disconnect(struct usb_device *dev, void *ptr)
acm
->
active
=
0
;
acm
->
present
=
0
;
if
(
acm
->
writing
){
usb_terminate_bulk
(
acm
->
dev
,
acm
->
writetransfer
);
if
(
acm
->
writing
)
acm
->
writing
=
0
;
}
if
(
acm
->
reading
){
usb_terminate_bulk
(
acm
->
dev
,
acm
->
readtransfer
);
if
(
acm
->
reading
)
acm
->
reading
=
0
;
if
(
acm
->
ctrlurb
)
{
usb_unlink_urb
(
acm
->
ctrlurb
);
usb_free_urb
(
acm
->
ctrlurb
);
acm
->
ctrlurb
=
NULL
;
}
if
(
acm
->
readurb
)
{
usb_unlink_urb
(
acm
->
readurb
);
usb_free_urb
(
acm
->
readurb
);
acm
->
readurb
=
NULL
;
}
if
(
acm
->
writeurb
)
{
usb_unlink_urb
(
acm
->
writeurb
);
usb_free_urb
(
acm
->
writeurb
);
acm
->
writeurb
=
NULL
;
}
usb_release_irq
(
acm
->
dev
,
acm
->
ctrltransfer
,
acm
->
ctrlpipe
);
//BUG: What to do if a device is open?? Notify process or not allow cleanup?
kfree
(
acm
->
writebuffer
);
kfree
(
acm
->
readbuffer
);
kfree
(
acm
->
ctrlbuffer
);
/* release the interfaces so that other drivers can have at them */
usb_driver_release_interface
(
&
acm_driver
,
...
...
fs/proc/base.c
View file @
159f5e24
...
...
@@ -513,7 +513,7 @@ static struct pid_entry base_stuff[] = {
E
(
PROC_PID_CMDLINE
,
"cmdline"
,
S_IFREG
|
S_IRUGO
),
E
(
PROC_PID_STAT
,
"stat"
,
S_IFREG
|
S_IRUGO
),
E
(
PROC_PID_STATM
,
"statm"
,
S_IFREG
|
S_IRUGO
),
#ifdef
SMP
#ifdef
__SMP__
E
(
PROC_PID_CPU
,
"cpu"
,
S_IFREG
|
S_IRUGO
),
#endif
#if CONFIG_AP1000
...
...
@@ -865,7 +865,7 @@ static struct dentry *proc_base_lookup(struct inode *dir, struct dentry *dentry)
case
PROC_PID_MAPS
:
inode
->
i_op
=
&
proc_maps_inode_operations
;
break
;
#ifdef
SMP
#ifdef
__SMP__
case
PROC_PID_CPU
:
inode
->
i_op
=
&
proc_info_inode_operations
;
inode
->
u
.
proc_i
.
op
.
proc_read
=
proc_pid_cpu
;
...
...
include/linux/i2c-old.h
View file @
159f5e24
...
...
@@ -42,6 +42,7 @@ struct i2c_device;
#define I2C_BUSID_PARPORT 2
/* Bit banging on a parallel port */
#define I2C_BUSID_BUZ 3
#define I2C_BUSID_ZORAN 4
#define I2C_BUSID_CYBER2000 5
/*
* struct for a driver for a i2c chip (tuner, soundprocessor,
...
...
include/linux/interrupt.h
View file @
159f5e24
...
...
@@ -80,5 +80,6 @@ enum {
*/
extern
unsigned
long
probe_irq_on
(
void
);
/* returns 0 on failure */
extern
int
probe_irq_off
(
unsigned
long
);
/* returns 0 or negative on failure */
extern
unsigned
int
probe_irq_mask
(
unsigned
long
);
/* returns mask of ISA interrupts */
#endif
include/linux/pci.h
View file @
159f5e24
...
...
@@ -299,6 +299,7 @@ struct pci_dev {
int
ro
;
/* Read/Only */
struct
pci_bus
*
bus
;
/* bus this device is on */
struct
pci_bus
*
subordinate
;
/* bus this device bridges to */
struct
pci_dev
*
sibling
;
/* next device on this bus */
struct
pci_dev
*
next
;
/* chain of all devices */
...
...
init/main.c
View file @
159f5e24
...
...
@@ -484,6 +484,7 @@ asmlinkage void __init start_kernel(void)
kmem_cache_init
();
sti
();
calibrate_delay
();
#if 0000
#ifdef CONFIG_BLK_DEV_INITRD
// FIXME, use the bootmem.h interface.
if (initrd_start && !initrd_below_start_ok && initrd_start < memory_start) {
...
...
@@ -492,6 +493,7 @@ asmlinkage void __init start_kernel(void)
initrd_start = 0;
}
#endif
#endif /* 0000 */
mem_init
();
kmem_cache_sizes_init
();
#ifdef CONFIG_PROC_FS
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment