Merge with git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git

This commit is contained in:
David Woodhouse 2006-04-17 15:35:18 +01:00
commit 94171db1d2
281 changed files with 5272 additions and 43322 deletions

View File

@ -33,7 +33,9 @@ pci_alloc_consistent(struct pci_dev *dev, size_t size,
Consistent memory is memory for which a write by either the device or
the processor can immediately be read by the processor or device
without having to worry about caching effects.
without having to worry about caching effects. (You may however need
to make sure to flush the processor's write buffers before telling
devices to read that memory.)
This routine allocates a region of <size> bytes of consistent memory.
it also returns a <dma_handle> which may be cast to an unsigned
@ -304,12 +306,12 @@ dma address with dma_mapping_error(). A non zero return value means the mapping
could not be created and the driver should take appropriate action (eg
reduce current DMA mapping usage or delay and try again later).
int
dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
enum dma_data_direction direction)
int
pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg,
int nents, int direction)
int
dma_map_sg(struct device *dev, struct scatterlist *sg,
int nents, enum dma_data_direction direction)
int
pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg,
int nents, int direction)
Maps a scatter gather list from the block layer.
@ -327,12 +329,33 @@ critical that the driver do something, in the case of a block driver
aborting the request or even oopsing is better than doing nothing and
corrupting the filesystem.
void
dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
enum dma_data_direction direction)
void
pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg,
int nents, int direction)
With scatterlists, you use the resulting mapping like this:
int i, count = dma_map_sg(dev, sglist, nents, direction);
struct scatterlist *sg;
for (i = 0, sg = sglist; i < count; i++, sg++) {
hw_address[i] = sg_dma_address(sg);
hw_len[i] = sg_dma_len(sg);
}
where nents is the number of entries in the sglist.
The implementation is free to merge several consecutive sglist entries
into one (e.g. with an IOMMU, or if several pages just happen to be
physically contiguous) and returns the actual number of sg entries it
mapped them to. On failure 0, is returned.
Then you should loop count times (note: this can be less than nents times)
and use sg_dma_address() and sg_dma_len() macros where you previously
accessed sg->address and sg->length as shown above.
void
dma_unmap_sg(struct device *dev, struct scatterlist *sg,
int nhwentries, enum dma_data_direction direction)
void
pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg,
int nents, int direction)
unmap the previously mapped scatter/gather list. All the parameters
must be the same as those and passed in to the scatter/gather mapping

View File

@ -58,11 +58,15 @@ translating each of those pages back to a kernel address using
something like __va(). [ EDIT: Update this when we integrate
Gerd Knorr's generic code which does this. ]
This rule also means that you may not use kernel image addresses
(ie. items in the kernel's data/text/bss segment, or your driver's)
nor may you use kernel stack addresses for DMA. Both of these items
might be mapped somewhere entirely different than the rest of physical
memory.
This rule also means that you may use neither kernel image addresses
(items in data/text/bss segments), nor module image addresses, nor
stack addresses for DMA. These could all be mapped somewhere entirely
different than the rest of physical memory. Even if those classes of
memory could physically work with DMA, you'd need to ensure the I/O
buffers were cacheline-aligned. Without that, you'd see cacheline
sharing problems (data corruption) on CPUs with DMA-incoherent caches.
(The CPU could write to one word, DMA would write to a different one
in the same cache line, and one of them could be overwritten.)
Also, this means that you cannot take the return of a kmap()
call and DMA to/from that. This is similar to vmalloc().
@ -284,6 +288,11 @@ There are two types of DMA mappings:
in order to get correct behavior on all platforms.
Also, on some platforms your driver may need to flush CPU write
buffers in much the same way as it needs to flush write buffers
found in PCI bridges (such as by reading a register's value
after writing it).
- Streaming DMA mappings which are usually mapped for one DMA transfer,
unmapped right after it (unless you use pci_dma_sync_* below) and for which
hardware can optimize for sequential accesses.
@ -303,6 +312,9 @@ There are two types of DMA mappings:
Neither type of DMA mapping has alignment restrictions that come
from PCI, although some devices may have such restrictions.
Also, systems with caches that aren't DMA-coherent will work better
when the underlying buffers don't share cache lines with other data.
Using Consistent DMA mappings.

View File

@ -12,18 +12,22 @@ meant as a replacement for the older, individual drivers:
teletext adapters)
It currently supports the following devices:
* Philips adapter
* home brew teletext adapter
* Velleman K8000 adapter
* ELV adapter
* Analog Devices evaluation boards (ADM1025, ADM1030, ADM1031, ADM1032)
* Barco LPT->DVI (K5800236) adapter
* (type=0) Philips adapter
* (type=1) home brew teletext adapter
* (type=2) Velleman K8000 adapter
* (type=3) ELV adapter
* (type=4) Analog Devices ADM1032 evaluation board
* (type=5) Analog Devices evaluation boards: ADM1025, ADM1030, ADM1031
* (type=6) Barco LPT->DVI (K5800236) adapter
These devices use different pinout configurations, so you have to tell
the driver what you have, using the type module parameter. There is no
way to autodetect the devices. Support for different pinout configurations
can be easily added when needed.
Earlier kernels defaulted to type=0 (Philips). But now, if the type
parameter is missing, the driver will simply fail to initialize.
Building your own adapter
-------------------------

View File

@ -0,0 +1,166 @@
The sync patches work is based on initial patches from
Krisztian <hidden@balabit.hu> and others and additional patches
from Jamal <hadi@cyberus.ca>.
The end goal for syncing is to be able to insert attributes + generate
events so that the an SA can be safely moved from one machine to another
for HA purposes.
The idea is to synchronize the SA so that the takeover machine can do
the processing of the SA as accurate as possible if it has access to it.
We already have the ability to generate SA add/del/upd events.
These patches add ability to sync and have accurate lifetime byte (to
ensure proper decay of SAs) and replay counters to avoid replay attacks
with as minimal loss at failover time.
This way a backup stays as closely uptodate as an active member.
Because the above items change for every packet the SA receives,
it is possible for a lot of the events to be generated.
For this reason, we also add a nagle-like algorithm to restrict
the events. i.e we are going to set thresholds to say "let me
know if the replay sequence threshold is reached or 10 secs have passed"
These thresholds are set system-wide via sysctls or can be updated
per SA.
The identified items that need to be synchronized are:
- the lifetime byte counter
note that: lifetime time limit is not important if you assume the failover
machine is known ahead of time since the decay of the time countdown
is not driven by packet arrival.
- the replay sequence for both inbound and outbound
1) Message Structure
----------------------
nlmsghdr:aevent_id:optional-TLVs.
The netlink message types are:
XFRM_MSG_NEWAE and XFRM_MSG_GETAE.
A XFRM_MSG_GETAE does not have TLVs.
A XFRM_MSG_NEWAE will have at least two TLVs (as is
discussed further below).
aevent_id structure looks like:
struct xfrm_aevent_id {
struct xfrm_usersa_id sa_id;
__u32 flags;
};
xfrm_usersa_id in this message layout identifies the SA.
flags are used to indicate different things. The possible
flags are:
XFRM_AE_RTHR=1, /* replay threshold*/
XFRM_AE_RVAL=2, /* replay value */
XFRM_AE_LVAL=4, /* lifetime value */
XFRM_AE_ETHR=8, /* expiry timer threshold */
XFRM_AE_CR=16, /* Event cause is replay update */
XFRM_AE_CE=32, /* Event cause is timer expiry */
XFRM_AE_CU=64, /* Event cause is policy update */
How these flags are used is dependent on the direction of the
message (kernel<->user) as well the cause (config, query or event).
This is described below in the different messages.
The pid will be set appropriately in netlink to recognize direction
(0 to the kernel and pid = processid that created the event
when going from kernel to user space)
A program needs to subscribe to multicast group XFRMNLGRP_AEVENTS
to get notified of these events.
2) TLVS reflect the different parameters:
-----------------------------------------
a) byte value (XFRMA_LTIME_VAL)
This TLV carries the running/current counter for byte lifetime since
last event.
b)replay value (XFRMA_REPLAY_VAL)
This TLV carries the running/current counter for replay sequence since
last event.
c)replay threshold (XFRMA_REPLAY_THRESH)
This TLV carries the threshold being used by the kernel to trigger events
when the replay sequence is exceeded.
d) expiry timer (XFRMA_ETIMER_THRESH)
This is a timer value in milliseconds which is used as the nagle
value to rate limit the events.
3) Default configurations for the parameters:
----------------------------------------------
By default these events should be turned off unless there is
at least one listener registered to listen to the multicast
group XFRMNLGRP_AEVENTS.
Programs installing SAs will need to specify the two thresholds, however,
in order to not change existing applications such as racoon
we also provide default threshold values for these different parameters
in case they are not specified.
the two sysctls/proc entries are:
a) /proc/sys/net/core/sysctl_xfrm_aevent_etime
used to provide default values for the XFRMA_ETIMER_THRESH in incremental
units of time of 100ms. The default is 10 (1 second)
b) /proc/sys/net/core/sysctl_xfrm_aevent_rseqth
used to provide default values for XFRMA_REPLAY_THRESH parameter
in incremental packet count. The default is two packets.
4) Message types
----------------
a) XFRM_MSG_GETAE issued by user-->kernel.
XFRM_MSG_GETAE does not carry any TLVs.
The response is a XFRM_MSG_NEWAE which is formatted based on what
XFRM_MSG_GETAE queried for.
The response will always have XFRMA_LTIME_VAL and XFRMA_REPLAY_VAL TLVs.
*if XFRM_AE_RTHR flag is set, then XFRMA_REPLAY_THRESH is also retrieved
*if XFRM_AE_ETHR flag is set, then XFRMA_ETIMER_THRESH is also retrieved
b) XFRM_MSG_NEWAE is issued by either user space to configure
or kernel to announce events or respond to a XFRM_MSG_GETAE.
i) user --> kernel to configure a specific SA.
any of the values or threshold parameters can be updated by passing the
appropriate TLV.
A response is issued back to the sender in user space to indicate success
or failure.
In the case of success, additionally an event with
XFRM_MSG_NEWAE is also issued to any listeners as described in iii).
ii) kernel->user direction as a response to XFRM_MSG_GETAE
The response will always have XFRMA_LTIME_VAL and XFRMA_REPLAY_VAL TLVs.
The threshold TLVs will be included if explicitly requested in
the XFRM_MSG_GETAE message.
iii) kernel->user to report as event if someone sets any values or
thresholds for an SA using XFRM_MSG_NEWAE (as described in #i above).
In such a case XFRM_AE_CU flag is set to inform the user that
the change happened as a result of an update.
The message will always have XFRMA_LTIME_VAL and XFRMA_REPLAY_VAL TLVs.
iv) kernel->user to report event when replay threshold or a timeout
is exceeded.
In such a case either XFRM_AE_CR (replay exceeded) or XFRM_AE_CE (timeout
happened) is set to inform the user what happened.
Note the two flags are mutually exclusive.
The message will always have XFRMA_LTIME_VAL and XFRMA_REPLAY_VAL TLVs.
Exceptions to threshold settings
--------------------------------
If you have an SA that is getting hit by traffic in bursts such that
there is a period where the timer threshold expires with no packets
seen, then an odd behavior is seen as follows:
The first packet arrival after a timer expiry will trigger a timeout
aevent; i.e we dont wait for a timeout period or a packet threshold
to be reached. This is done for simplicity and efficiency reasons.
-JHS

View File

@ -3,14 +3,11 @@
--------------------
$Id: driver,v 1.10 2002/07/22 15:27:30 rmk Exp $
This document is meant as a brief overview of some aspects of the new serial
driver. It is not complete, any questions you have should be directed to
<rmk@arm.linux.org.uk>
The reference implementation is contained within serial_amba.c.
The reference implementation is contained within amba_pl011.c.
@ -31,6 +28,11 @@ The serial core provides a few helper functions. This includes identifing
the correct port structure (via uart_get_console) and decoding command line
arguments (uart_parse_options).
There is also a helper function (uart_write_console) which performs a
character by character write, translating newlines to CRLF sequences.
Driver writers are recommended to use this function rather than implementing
their own version.
Locking
-------
@ -86,6 +88,7 @@ hardware.
- TIOCM_DTR DTR signal.
- TIOCM_OUT1 OUT1 signal.
- TIOCM_OUT2 OUT2 signal.
- TIOCM_LOOP Set the port into loopback mode.
If the appropriate bit is set, the signal should be driven
active. If the bit is clear, the signal should be driven
inactive.
@ -141,6 +144,10 @@ hardware.
enable_ms(port)
Enable the modem status interrupts.
This method may be called multiple times. Modem status
interrupts should be disabled when the shutdown method is
called.
Locking: port->lock taken.
Interrupts: locally disabled.
This call must not sleep
@ -160,6 +167,8 @@ hardware.
state. Enable the port for reception. It should not activate
RTS nor DTR; this will be done via a separate call to set_mctrl.
This method will only be called when the port is initially opened.
Locking: port_sem taken.
Interrupts: globally disabled.
@ -169,6 +178,11 @@ hardware.
RTS nor DTR; this will have already been done via a separate
call to set_mctrl.
Drivers must not access port->info once this call has completed.
This method will only be called when there are no more users of
this port.
Locking: port_sem taken.
Interrupts: caller dependent.

View File

@ -3058,13 +3058,6 @@ M: khali@linux-fr.org
L: lm-sensors@lm-sensors.org
S: Odd Fixes
WAN ROUTER & SANGOMA WANPIPE DRIVERS & API (X.25, FRAME RELAY, PPP, CISCO HDLC)
P: Nenad Corbic
M: ncorbic@sangoma.com
M: dm@sangoma.com
W: http://www.sangoma.com
S: Supported
WATCHDOG DEVICE DRIVERS
P: Wim Van Sebroeck
M: wim@iguana.be

View File

@ -194,13 +194,23 @@ void __init at91_add_device_eth(struct at91_eth_data *data) {}
#if defined(CONFIG_AT91_CF) || defined(CONFIG_AT91_CF_MODULE)
static struct at91_cf_data cf_data;
static struct resource at91_cf_resources[] = {
[0] = {
.start = AT91_CF_BASE,
/* ties up CS4, CS5, and CS6 */
.end = AT91_CF_BASE + (0x30000000 - 1),
.flags = IORESOURCE_MEM | IORESOURCE_MEM_8AND16BIT,
},
};
static struct platform_device at91rm9200_cf_device = {
.name = "at91_cf",
.id = -1,
.dev = {
.platform_data = &cf_data,
},
.num_resources = 0,
.resource = at91_cf_resources,
.num_resources = ARRAY_SIZE(at91_cf_resources),
};
void __init at91_add_device_cf(struct at91_cf_data *data)

View File

@ -50,7 +50,7 @@ static struct mtd_partition smdk_default_nand_part[] = {
.offset = 0,
},
[1] = {
.name = "S3C2410 flash parition 1",
.name = "S3C2410 flash partition 1",
.offset = 0,
.size = SZ_2M,
},

View File

@ -139,7 +139,7 @@ static int s3c2440_clk_add(struct sys_device *sysdev)
clkdivn = __raw_readl(S3C2410_CLKDIVN);
clkdivn |= S3C2440_CLKDIVN_UCLK;
__raw_writel(camdivn, S3C2410_CLKDIVN);
__raw_writel(clkdivn, S3C2410_CLKDIVN);
mutex_unlock(&clocks_mutex);
}

View File

@ -6,7 +6,7 @@ extra-y := head.o init_task.o vmlinux.lds
obj-y := process.o semaphore.o signal.o entry.o traps.o irq.o \
ptrace.o time.o ioport.o ldt.o setup.o i8259.o sys_i386.o \
pci-dma.o i386_ksyms.o i387.o dmi_scan.o bootflag.o \
pci-dma.o i386_ksyms.o i387.o bootflag.o \
quirks.o i8237.o topology.o alternative.o
obj-y += cpu/

View File

@ -314,3 +314,4 @@ ENTRY(sys_call_table)
.long sys_get_robust_list
.long sys_splice
.long sys_sync_file_range
.long sys_tee /* 315 */

View File

@ -588,7 +588,10 @@ static __init int via_router_probe(struct irq_router *r,
case PCI_DEVICE_ID_VIA_82C596:
case PCI_DEVICE_ID_VIA_82C686:
case PCI_DEVICE_ID_VIA_8231:
case PCI_DEVICE_ID_VIA_8233A:
case PCI_DEVICE_ID_VIA_8235:
case PCI_DEVICE_ID_VIA_8237:
case PCI_DEVICE_ID_VIA_8237_SATA:
/* FIXME: add new ones for 8233/5 */
r->name = "VIA";
r->get = pirq_via_get;

View File

@ -7,7 +7,7 @@ extra-y := head.o init_task.o vmlinux.lds
obj-y := acpi.o entry.o efi.o efi_stub.o gate-data.o fsys.o ia64_ksyms.o irq.o irq_ia64.o \
irq_lsapic.o ivt.o machvec.o pal.o patch.o process.o perfmon.o ptrace.o sal.o \
salinfo.o semaphore.o setup.o signal.o sys_ia64.o time.o traps.o unaligned.o \
unwind.o mca.o mca_asm.o topology.o dmi_scan.o
unwind.o mca.o mca_asm.o topology.o
obj-$(CONFIG_IA64_BRL_EMU) += brl_emu.o
obj-$(CONFIG_IA64_GENERIC) += acpi-ext.o
@ -30,7 +30,6 @@ obj-$(CONFIG_IA64_MCA_RECOVERY) += mca_recovery.o
obj-$(CONFIG_KPROBES) += kprobes.o jprobes.o
obj-$(CONFIG_IA64_UNCACHED_ALLOCATOR) += uncached.o
mca_recovery-y += mca_drv.o mca_drv_asm.o
dmi_scan-y += ../../i386/kernel/dmi_scan.o
# The gate DSO image is built using a special linker script.
targets += gate.so gate-syms.o

View File

@ -1609,5 +1609,6 @@ sys_call_table:
data8 sys_set_robust_list
data8 sys_get_robust_list
data8 sys_sync_file_range // 1300
data8 sys_tee
.org sys_call_table + 8*NR_syscalls // guard against failures to increase NR_syscalls

View File

@ -963,7 +963,7 @@ no_mod:
*/
static void
ia64_wait_for_slaves(int monarch)
ia64_wait_for_slaves(int monarch, const char *type)
{
int c, wait = 0, missing = 0;
for_each_online_cpu(c) {
@ -989,7 +989,7 @@ ia64_wait_for_slaves(int monarch)
}
if (!missing)
goto all_in;
printk(KERN_INFO "OS MCA slave did not rendezvous on cpu");
printk(KERN_INFO "OS %s slave did not rendezvous on cpu", type);
for_each_online_cpu(c) {
if (c == monarch)
continue;
@ -1000,7 +1000,7 @@ ia64_wait_for_slaves(int monarch)
return;
all_in:
printk(KERN_INFO "All OS MCA slaves have reached rendezvous\n");
printk(KERN_INFO "All OS %s slaves have reached rendezvous\n", type);
return;
}
@ -1038,7 +1038,7 @@ ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw,
if (notify_die(DIE_MCA_MONARCH_ENTER, "MCA", regs, (long)&nd, 0, 0)
== NOTIFY_STOP)
ia64_mca_spin(__FUNCTION__);
ia64_wait_for_slaves(cpu);
ia64_wait_for_slaves(cpu, "MCA");
/* Wakeup all the processors which are spinning in the rendezvous loop.
* They will leave SAL, then spin in the OS with interrupts disabled
@ -1429,7 +1429,7 @@ ia64_init_handler(struct pt_regs *regs, struct switch_stack *sw,
*/
printk("Delaying for 5 seconds...\n");
udelay(5*1000000);
ia64_wait_for_slaves(cpu);
ia64_wait_for_slaves(cpu, "INIT");
/* If nobody intercepts DIE_INIT_MONARCH_PROCESS then we drop through
* to default_monarch_init_process() above and just print all the
* tasks.

View File

@ -519,6 +519,68 @@ void __cpuinit *per_cpu_init(void)
}
#endif /* CONFIG_SMP */
#ifdef CONFIG_VIRTUAL_MEM_MAP
static inline int find_next_valid_pfn_for_pgdat(pg_data_t *pgdat, int i)
{
unsigned long end_address, hole_next_pfn;
unsigned long stop_address;
end_address = (unsigned long) &vmem_map[pgdat->node_start_pfn + i];
end_address = PAGE_ALIGN(end_address);
stop_address = (unsigned long) &vmem_map[
pgdat->node_start_pfn + pgdat->node_spanned_pages];
do {
pgd_t *pgd;
pud_t *pud;
pmd_t *pmd;
pte_t *pte;
pgd = pgd_offset_k(end_address);
if (pgd_none(*pgd)) {
end_address += PGDIR_SIZE;
continue;
}
pud = pud_offset(pgd, end_address);
if (pud_none(*pud)) {
end_address += PUD_SIZE;
continue;
}
pmd = pmd_offset(pud, end_address);
if (pmd_none(*pmd)) {
end_address += PMD_SIZE;
continue;
}
pte = pte_offset_kernel(pmd, end_address);
retry_pte:
if (pte_none(*pte)) {
end_address += PAGE_SIZE;
pte++;
if ((end_address < stop_address) &&
(end_address != ALIGN(end_address, 1UL << PMD_SHIFT)))
goto retry_pte;
continue;
}
/* Found next valid vmem_map page */
break;
} while (end_address < stop_address);
end_address = min(end_address, stop_address);
end_address = end_address - (unsigned long) vmem_map + sizeof(struct page) - 1;
hole_next_pfn = end_address / sizeof(struct page);
return hole_next_pfn - pgdat->node_start_pfn;
}
#else
static inline int find_next_valid_pfn_for_pgdat(pg_data_t *pgdat, int i)
{
return i + 1;
}
#endif
/**
* show_mem - give short summary of memory stats
*
@ -547,8 +609,10 @@ void show_mem(void)
struct page *page;
if (pfn_valid(pgdat->node_start_pfn + i))
page = pfn_to_page(pgdat->node_start_pfn + i);
else
else {
i = find_next_valid_pfn_for_pgdat(pgdat, i) - 1;
continue;
}
if (PageReserved(page))
reserved++;
else if (PageSwapCache(page))

View File

@ -323,3 +323,4 @@ COMPAT_SYS(pselect6)
COMPAT_SYS(ppoll)
SYSCALL(unshare)
SYSCALL(splice)
SYSCALL(tee)

View File

@ -75,7 +75,7 @@ sys_call_table:
/*265*/ .long sys_timer_delete, sys_timer_create, sys_nis_syscall, sys_io_setup, sys_io_destroy
/*270*/ .long sys_io_submit, sys_io_cancel, sys_io_getevents, sys_mq_open, sys_mq_unlink
/*275*/ .long sys_mq_timedsend, sys_mq_timedreceive, sys_mq_notify, sys_mq_getsetattr, sys_waitid
/*280*/ .long sys_ni_syscall, sys_add_key, sys_request_key, sys_keyctl, sys_openat
/*280*/ .long sys_tee, sys_add_key, sys_request_key, sys_keyctl, sys_openat
/*285*/ .long sys_mkdirat, sys_mknodat, sys_fchownat, sys_futimesat, sys_fstatat64
/*290*/ .long sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat
/*295*/ .long sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll, sys_unshare

View File

@ -138,6 +138,7 @@ SIGN2(sys32_ioprio_get, sys_ioprio_get, %o0, %o1)
SIGN3(sys32_ioprio_set, sys_ioprio_set, %o0, %o1, %o2)
SIGN2(sys32_splice, sys_splice, %o0, %o1)
SIGN2(sys32_sync_file_range, compat_sync_file_range, %o0, %o5)
SIGN2(sys32_tee, sys_tee, %o0, %o1)
.globl sys32_mmap2
sys32_mmap2:

View File

@ -76,7 +76,7 @@ sys_call_table32:
.word sys_timer_delete, compat_sys_timer_create, sys_ni_syscall, compat_sys_io_setup, sys_io_destroy
/*270*/ .word sys32_io_submit, sys_io_cancel, compat_sys_io_getevents, sys32_mq_open, sys_mq_unlink
.word compat_sys_mq_timedsend, compat_sys_mq_timedreceive, compat_sys_mq_notify, compat_sys_mq_getsetattr, compat_sys_waitid
/*280*/ .word sys_ni_syscall, sys_add_key, sys_request_key, sys_keyctl, compat_sys_openat
/*280*/ .word sys32_tee, sys_add_key, sys_request_key, sys_keyctl, compat_sys_openat
.word sys_mkdirat, sys_mknodat, sys_fchownat, compat_sys_futimesat, compat_sys_fstatat64
/*285*/ .word sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat
.word sys_fchmodat, sys_faccessat, compat_sys_pselect6, compat_sys_ppoll, sys_unshare
@ -145,7 +145,7 @@ sys_call_table:
.word sys_timer_delete, sys_timer_create, sys_ni_syscall, sys_io_setup, sys_io_destroy
/*270*/ .word sys_io_submit, sys_io_cancel, sys_io_getevents, sys_mq_open, sys_mq_unlink
.word sys_mq_timedsend, sys_mq_timedreceive, sys_mq_notify, sys_mq_getsetattr, sys_waitid
/*280*/ .word sys_nis_syscall, sys_add_key, sys_request_key, sys_keyctl, sys_openat
/*280*/ .word sys_tee, sys_add_key, sys_request_key, sys_keyctl, sys_openat
.word sys_mkdirat, sys_mknodat, sys_fchownat, sys_futimesat, sys_fstatat64
/*285*/ .word sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat
.word sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll, sys_unshare

View File

@ -8,7 +8,7 @@ obj-y := process.o signal.o entry.o traps.o irq.o \
ptrace.o time.o ioport.o ldt.o setup.o i8259.o sys_x86_64.o \
x8664_ksyms.o i387.o syscall.o vsyscall.o \
setup64.o bootflag.o e820.o reboot.o quirks.o i8237.o \
dmi_scan.o pci-dma.o pci-nommu.o
pci-dma.o pci-nommu.o
obj-$(CONFIG_X86_MCE) += mce.o
obj-$(CONFIG_X86_MCE_INTEL) += mce_intel.o
@ -49,5 +49,3 @@ intel_cacheinfo-y += ../../i386/kernel/cpu/intel_cacheinfo.o
quirks-y += ../../i386/kernel/quirks.o
i8237-y += ../../i386/kernel/i8237.o
msr-$(subst m,y,$(CONFIG_X86_MSR)) += ../../i386/kernel/msr.o
dmi_scan-y += ../../i386/kernel/dmi_scan.o

View File

@ -350,16 +350,51 @@ out:
return ret;
}
/**
* sg_scsi_ioctl -- handle deprecated SCSI_IOCTL_SEND_COMMAND ioctl
* @file: file this ioctl operates on (optional)
* @q: request queue to send scsi commands down
* @disk: gendisk to operate on (option)
* @sic: userspace structure describing the command to perform
*
* Send down the scsi command described by @sic to the device below
* the request queue @q. If @file is non-NULL it's used to perform
* fine-grained permission checks that allow users to send down
* non-destructive SCSI commands. If the caller has a struct gendisk
* available it should be passed in as @disk to allow the low level
* driver to use the information contained in it. A non-NULL @disk
* is only allowed if the caller knows that the low level driver doesn't
* need it (e.g. in the scsi subsystem).
*
* Notes:
* - This interface is deprecated - users should use the SG_IO
* interface instead, as this is a more flexible approach to
* performing SCSI commands on a device.
* - The SCSI command length is determined by examining the 1st byte
* of the given command. There is no way to override this.
* - Data transfers are limited to PAGE_SIZE
* - The length (x + y) must be at least OMAX_SB_LEN bytes long to
* accommodate the sense buffer when an error occurs.
* The sense buffer is truncated to OMAX_SB_LEN (16) bytes so that
* old code will not be surprised.
* - If a Unix error occurs (e.g. ENOMEM) then the user will receive
* a negative return and the Unix error code in 'errno'.
* If the SCSI command succeeds then 0 is returned.
* Positive numbers returned are the compacted SCSI error codes (4
* bytes in one int) where the lowest byte is the SCSI status.
*/
#define OMAX_SB_LEN 16 /* For backward compatibility */
static int sg_scsi_ioctl(struct file *file, request_queue_t *q,
struct gendisk *bd_disk, Scsi_Ioctl_Command __user *sic)
int sg_scsi_ioctl(struct file *file, struct request_queue *q,
struct gendisk *disk, struct scsi_ioctl_command __user *sic)
{
struct request *rq;
int err;
unsigned int in_len, out_len, bytes, opcode, cmdlen;
char *buffer = NULL, sense[SCSI_SENSE_BUFFERSIZE];
if (!sic)
return -EINVAL;
/*
* get in an out lengths, verify they don't exceed a page worth of data
*/
@ -393,45 +428,53 @@ static int sg_scsi_ioctl(struct file *file, request_queue_t *q,
if (copy_from_user(rq->cmd, sic->data, cmdlen))
goto error;
if (copy_from_user(buffer, sic->data + cmdlen, in_len))
if (in_len && copy_from_user(buffer, sic->data + cmdlen, in_len))
goto error;
err = verify_command(file, rq->cmd);
if (err)
goto error;
/* default. possible overriden later */
rq->retries = 5;
switch (opcode) {
case SEND_DIAGNOSTIC:
case FORMAT_UNIT:
rq->timeout = FORMAT_UNIT_TIMEOUT;
break;
case START_STOP:
rq->timeout = START_STOP_TIMEOUT;
break;
case MOVE_MEDIUM:
rq->timeout = MOVE_MEDIUM_TIMEOUT;
break;
case READ_ELEMENT_STATUS:
rq->timeout = READ_ELEMENT_STATUS_TIMEOUT;
break;
case READ_DEFECT_DATA:
rq->timeout = READ_DEFECT_DATA_TIMEOUT;
break;
default:
rq->timeout = BLK_DEFAULT_TIMEOUT;
break;
case SEND_DIAGNOSTIC:
case FORMAT_UNIT:
rq->timeout = FORMAT_UNIT_TIMEOUT;
rq->retries = 1;
break;
case START_STOP:
rq->timeout = START_STOP_TIMEOUT;
break;
case MOVE_MEDIUM:
rq->timeout = MOVE_MEDIUM_TIMEOUT;
break;
case READ_ELEMENT_STATUS:
rq->timeout = READ_ELEMENT_STATUS_TIMEOUT;
break;
case READ_DEFECT_DATA:
rq->timeout = READ_DEFECT_DATA_TIMEOUT;
rq->retries = 1;
break;
default:
rq->timeout = BLK_DEFAULT_TIMEOUT;
break;
}
if (bytes && blk_rq_map_kern(q, rq, buffer, bytes, __GFP_WAIT)) {
err = DRIVER_ERROR << 24;
goto out;
}
memset(sense, 0, sizeof(sense));
rq->sense = sense;
rq->sense_len = 0;
rq->data = buffer;
rq->data_len = bytes;
rq->flags |= REQ_BLOCK_PC;
rq->retries = 0;
blk_execute_rq(q, bd_disk, rq, 0);
blk_execute_rq(q, disk, rq, 0);
out:
err = rq->errors & 0xff; /* only 8 bit SCSI status */
if (err) {
if (rq->sense_len && rq->sense) {
@ -450,7 +493,7 @@ error:
blk_put_request(rq);
return err;
}
EXPORT_SYMBOL_GPL(sg_scsi_ioctl);
/* Send basic block requests */
static int __blk_send_generic(request_queue_t *q, struct gendisk *bd_disk, int cmd, int data)

View File

@ -188,6 +188,11 @@ static ssize_t driver_bind(struct device_driver *drv,
up(&dev->sem);
if (dev->parent)
up(&dev->parent->sem);
if (err > 0) /* success */
err = count;
else if (err == 0) /* driver didn't accept device */
err = -ENODEV;
}
put_device(dev);
put_bus(bus);

View File

@ -562,14 +562,13 @@ int class_device_add(struct class_device *class_dev)
kobject_uevent(&class_dev->kobj, KOBJ_ADD);
/* notify any interfaces this device is now here */
if (parent_class) {
down(&parent_class->sem);
list_add_tail(&class_dev->node, &parent_class->children);
list_for_each_entry(class_intf, &parent_class->interfaces, node)
if (class_intf->add)
class_intf->add(class_dev, class_intf);
up(&parent_class->sem);
down(&parent_class->sem);
list_add_tail(&class_dev->node, &parent_class->children);
list_for_each_entry(class_intf, &parent_class->interfaces, node) {
if (class_intf->add)
class_intf->add(class_dev, class_intf);
}
up(&parent_class->sem);
register_done:
if (error) {

View File

@ -209,7 +209,7 @@ static void __device_release_driver(struct device * dev)
sysfs_remove_link(&dev->kobj, "driver");
klist_remove(&dev->knode_driver);
if (dev->bus->remove)
if (dev->bus && dev->bus->remove)
dev->bus->remove(dev);
else if (drv->remove)
drv->remove(dev);

View File

@ -10,6 +10,8 @@
#include <linux/vt_kern.h>
#include <linux/device.h>
#include <linux/kallsyms.h>
#include <linux/pm.h>
#include "../base.h"
#include "power.h"
@ -58,6 +60,7 @@ int suspend_device(struct device * dev, pm_message_t state)
if (dev->bus && dev->bus->suspend && !dev->power.power_state.event) {
dev_dbg(dev, "suspending\n");
error = dev->bus->suspend(dev, state);
suspend_report_result(dev->bus->suspend, error);
}
up(&dev->sem);
return error;
@ -169,3 +172,12 @@ int device_power_down(pm_message_t state)
EXPORT_SYMBOL_GPL(device_power_down);
void __suspend_report_result(const char *function, void *fn, int ret)
{
if (ret) {
printk(KERN_ERR "%s(): ", function);
print_fn_descriptor_symbol("%s() returns ", (unsigned long)fn);
printk("%d\n", ret);
}
}
EXPORT_SYMBOL_GPL(__suspend_report_result);

View File

@ -64,6 +64,12 @@ static struct gatt_mask efficeon_generic_masks[] =
{.mask = 0x00000001, .type = 0}
};
/* This function does the same thing as mask_memory() for this chipset... */
static inline unsigned long efficeon_mask_memory(unsigned long addr)
{
return addr | 0x00000001;
}
static struct aper_size_info_lvl2 efficeon_generic_sizes[4] =
{
{256, 65536, 0},
@ -251,7 +257,7 @@ static int efficeon_insert_memory(struct agp_memory * mem, off_t pg_start, int t
last_page = NULL;
for (i = 0; i < count; i++) {
int index = pg_start + i;
unsigned long insert = mem->memory[i];
unsigned long insert = efficeon_mask_memory(mem->memory[i]);
page = (unsigned int *) efficeon_private.l1_table[index >> 10];

View File

@ -2734,7 +2734,7 @@ static void __do_SAK(void *arg)
printk(KERN_NOTICE "SAK: killed process %d"
" (%s): fd#%d opened to the tty\n",
p->pid, p->comm, i);
send_sig(SIGKILL, p, 1);
force_sig(SIGKILL, p);
break;
}
}

View File

@ -1,7 +1,8 @@
#
# Makefile for the linux kernel.
#
obj-$(CONFIG_EDD) += edd.o
obj-$(CONFIG_DMI) += dmi_scan.o
obj-$(CONFIG_EDD) += edd.o
obj-$(CONFIG_EFI_VARS) += efivars.o
obj-$(CONFIG_EFI_PCDP) += pcdp.o
obj-$(CONFIG_DELL_RBU) += dell_rbu.o

View File

@ -27,7 +27,7 @@ static char * __init dmi_string(struct dmi_header *dm, u8 s)
else
printk(KERN_ERR "dmi_string: out of memory.\n");
}
}
}
return str;
}
@ -41,7 +41,7 @@ static int __init dmi_table(u32 base, int len, int num,
{
u8 *buf, *data;
int i = 0;
buf = dmi_ioremap(base, len);
if (buf == NULL)
return -1;
@ -49,9 +49,9 @@ static int __init dmi_table(u32 base, int len, int num,
data = buf;
/*
* Stop when we see all the items the table claimed to have
* OR we run off the end of the table (also happens)
*/
* Stop when we see all the items the table claimed to have
* OR we run off the end of the table (also happens)
*/
while ((i < num) && (data - buf + sizeof(struct dmi_header)) <= len) {
struct dmi_header *dm = (struct dmi_header *)data;
/*
@ -75,7 +75,7 @@ static int __init dmi_checksum(u8 *buf)
{
u8 sum = 0;
int a;
for (a = 0; a < 15; a++)
sum += buf[a];

View File

@ -1161,7 +1161,7 @@ w83792d_detect(struct i2c_adapter *adapter, int address, int kind)
bank. */
if (kind < 0) {
if (w83792d_read_value(client, W83792D_REG_CONFIG) & 0x80) {
dev_warn(dev, "Detection failed at step 3\n");
dev_dbg(dev, "Detection failed at step 1\n");
goto ERROR1;
}
val1 = w83792d_read_value(client, W83792D_REG_BANK);
@ -1170,6 +1170,7 @@ w83792d_detect(struct i2c_adapter *adapter, int address, int kind)
if (!(val1 & 0x07)) { /* is Bank0 */
if (((!(val1 & 0x80)) && (val2 != 0xa3)) ||
((val1 & 0x80) && (val2 != 0x5c))) {
dev_dbg(dev, "Detection failed at step 2\n");
goto ERROR1;
}
}
@ -1177,7 +1178,7 @@ w83792d_detect(struct i2c_adapter *adapter, int address, int kind)
should match */
if (w83792d_read_value(client,
W83792D_REG_I2C_ADDR) != address) {
dev_warn(dev, "Detection failed at step 5\n");
dev_dbg(dev, "Detection failed at step 3\n");
goto ERROR1;
}
}

View File

@ -286,7 +286,10 @@ config I2C_PARPORT
This driver is a replacement for (and was inspired by) an older
driver named i2c-philips-par. The new driver supports more devices,
and makes it easier to add support for new devices.
An adapter type parameter is now mandatory. Please read the file
Documentation/i2c/busses/i2c-parport for details.
Another driver exists, named i2c-parport-light, which doesn't depend
on the parport driver. This is meant for embedded systems. Don't say
Y here if you intend to say Y or M there.

View File

@ -121,9 +121,14 @@ static struct i2c_adapter parport_adapter = {
static int __init i2c_parport_init(void)
{
if (type < 0 || type >= ARRAY_SIZE(adapter_parm)) {
if (type < 0) {
printk(KERN_WARNING "i2c-parport: adapter type unspecified\n");
return -ENODEV;
}
if (type >= ARRAY_SIZE(adapter_parm)) {
printk(KERN_WARNING "i2c-parport: invalid type (%d)\n", type);
type = 0;
return -ENODEV;
}
if (base == 0) {

View File

@ -241,9 +241,14 @@ static struct parport_driver i2c_parport_driver = {
static int __init i2c_parport_init(void)
{
if (type < 0 || type >= ARRAY_SIZE(adapter_parm)) {
if (type < 0) {
printk(KERN_WARNING "i2c-parport: adapter type unspecified\n");
return -ENODEV;
}
if (type >= ARRAY_SIZE(adapter_parm)) {
printk(KERN_WARNING "i2c-parport: invalid type (%d)\n", type);
type = 0;
return -ENODEV;
}
return parport_register_driver(&i2c_parport_driver);

View File

@ -90,7 +90,7 @@ static struct adapter_parm adapter_parm[] = {
},
};
static int type;
static int type = -1;
module_param(type, int, 0);
MODULE_PARM_DESC(type,
"Type of adapter:\n"

View File

@ -43,13 +43,6 @@
#include <linux/init.h>
#include <asm/io.h>
/*
HISTORY:
2003-05-11 1.0.0 Updated from lm_sensors project for kernel 2.5
(was i2c-sis645.c from lm_sensors 2.7.0)
*/
#define SIS96x_VERSION "1.0.0"
/* base address register in PCI config space */
#define SIS96x_BAR 0x04
@ -337,7 +330,6 @@ static struct pci_driver sis96x_driver = {
static int __init i2c_sis96x_init(void)
{
printk(KERN_INFO "i2c-sis96x version %s\n", SIS96x_VERSION);
return pci_register_driver(&sis96x_driver);
}

View File

@ -27,6 +27,7 @@
#include <linux/rtc.h>
#include <linux/bcd.h>
#include <linux/mutex.h>
#include <linux/workqueue.h>
#define DS1374_REG_TOD0 0x00
#define DS1374_REG_TOD1 0x01
@ -139,7 +140,7 @@ ulong ds1374_get_rtc_time(void)
return t1;
}
static void ds1374_set_tlet(ulong arg)
static void ds1374_set_work(void *arg)
{
ulong t1, t2;
int limit = 10; /* arbitrary retry limit */
@ -168,17 +169,18 @@ static void ds1374_set_tlet(ulong arg)
static ulong new_time;
static DECLARE_TASKLET_DISABLED(ds1374_tasklet, ds1374_set_tlet,
(ulong) & new_time);
static struct workqueue_struct *ds1374_workqueue;
static DECLARE_WORK(ds1374_work, ds1374_set_work, &new_time);
int ds1374_set_rtc_time(ulong nowtime)
{
new_time = nowtime;
if (in_interrupt())
tasklet_schedule(&ds1374_tasklet);
queue_work(ds1374_workqueue, &ds1374_work);
else
ds1374_set_tlet((ulong) & new_time);
ds1374_set_work(&new_time);
return 0;
}
@ -204,6 +206,8 @@ static int ds1374_probe(struct i2c_adapter *adap, int addr, int kind)
client->adapter = adap;
client->driver = &ds1374_driver;
ds1374_workqueue = create_singlethread_workqueue("ds1374");
if ((rc = i2c_attach_client(client)) != 0) {
kfree(client);
return rc;
@ -227,7 +231,7 @@ static int ds1374_detach(struct i2c_client *client)
if ((rc = i2c_detach_client(client)) == 0) {
kfree(i2c_get_clientdata(client));
tasklet_kill(&ds1374_tasklet);
destroy_workqueue(ds1374_workqueue);
}
return rc;
}

View File

@ -25,6 +25,7 @@
#include <linux/rtc.h>
#include <linux/bcd.h>
#include <linux/mutex.h>
#include <linux/workqueue.h>
#include <asm/time.h>
#include <asm/rtc.h>
@ -111,7 +112,7 @@ m41t00_get_rtc_time(void)
}
static void
m41t00_set_tlet(ulong arg)
m41t00_set(void *arg)
{
struct rtc_time tm;
ulong nowtime = *(ulong *)arg;
@ -145,9 +146,9 @@ m41t00_set_tlet(ulong arg)
return;
}
static ulong new_time;
DECLARE_TASKLET_DISABLED(m41t00_tasklet, m41t00_set_tlet, (ulong)&new_time);
static ulong new_time;
static struct workqueue_struct *m41t00_wq;
static DECLARE_WORK(m41t00_work, m41t00_set, &new_time);
int
m41t00_set_rtc_time(ulong nowtime)
@ -155,9 +156,9 @@ m41t00_set_rtc_time(ulong nowtime)
new_time = nowtime;
if (in_interrupt())
tasklet_schedule(&m41t00_tasklet);
queue_work(m41t00_wq, &m41t00_work);
else
m41t00_set_tlet((ulong)&new_time);
m41t00_set(&new_time);
return 0;
}
@ -189,6 +190,7 @@ m41t00_probe(struct i2c_adapter *adap, int addr, int kind)
return rc;
}
m41t00_wq = create_singlethread_workqueue("m41t00");
save_client = client;
return 0;
}
@ -206,7 +208,7 @@ m41t00_detach(struct i2c_client *client)
if ((rc = i2c_detach_client(client)) == 0) {
kfree(client);
tasklet_kill(&m41t00_tasklet);
destroy_workqueue(m41t00_wq);
}
return rc;
}

View File

@ -302,7 +302,7 @@ static void ib_cache_setup_one(struct ib_device *device)
kmalloc(sizeof *device->cache.pkey_cache *
(end_port(device) - start_port(device) + 1), GFP_KERNEL);
device->cache.gid_cache =
kmalloc(sizeof *device->cache.pkey_cache *
kmalloc(sizeof *device->cache.gid_cache *
(end_port(device) - start_port(device) + 1), GFP_KERNEL);
if (!device->cache.pkey_cache || !device->cache.gid_cache) {

View File

@ -2311,6 +2311,7 @@ static void local_completions(void *data)
local = list_entry(mad_agent_priv->local_list.next,
struct ib_mad_local_private,
completion_list);
list_del(&local->completion_list);
spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
if (local->mad_priv) {
recv_mad_agent = local->recv_mad_agent;
@ -2362,7 +2363,6 @@ local_send_completion:
&mad_send_wc);
spin_lock_irqsave(&mad_agent_priv->lock, flags);
list_del(&local->completion_list);
atomic_dec(&mad_agent_priv->refcount);
if (!recv)
kmem_cache_free(ib_mad_cache, local->mad_priv);

View File

@ -45,6 +45,40 @@
#include <rdma/ib_verbs.h>
#include <rdma/ib_cache.h>
int ib_rate_to_mult(enum ib_rate rate)
{
switch (rate) {
case IB_RATE_2_5_GBPS: return 1;
case IB_RATE_5_GBPS: return 2;
case IB_RATE_10_GBPS: return 4;
case IB_RATE_20_GBPS: return 8;
case IB_RATE_30_GBPS: return 12;
case IB_RATE_40_GBPS: return 16;
case IB_RATE_60_GBPS: return 24;
case IB_RATE_80_GBPS: return 32;
case IB_RATE_120_GBPS: return 48;
default: return -1;
}
}
EXPORT_SYMBOL(ib_rate_to_mult);
enum ib_rate mult_to_ib_rate(int mult)
{
switch (mult) {
case 1: return IB_RATE_2_5_GBPS;
case 2: return IB_RATE_5_GBPS;
case 4: return IB_RATE_10_GBPS;
case 8: return IB_RATE_20_GBPS;
case 12: return IB_RATE_30_GBPS;
case 16: return IB_RATE_40_GBPS;
case 24: return IB_RATE_60_GBPS;
case 32: return IB_RATE_80_GBPS;
case 48: return IB_RATE_120_GBPS;
default: return IB_RATE_PORT_CURRENT;
}
}
EXPORT_SYMBOL(mult_to_ib_rate);
/* Protection domains */
struct ib_pd *ib_alloc_pd(struct ib_device *device)

View File

@ -7,10 +7,11 @@ config INFINIBAND_MTHCA
("Tavor") and the MT25208 PCI Express HCA ("Arbel").
config INFINIBAND_MTHCA_DEBUG
bool "Verbose debugging output"
bool "Verbose debugging output" if EMBEDDED
depends on INFINIBAND_MTHCA
default n
default y
---help---
This option causes the mthca driver produce a bunch of debug
messages. Select this is you are developing the driver or
trying to diagnose a problem.
This option causes debugging code to be compiled into the
mthca driver. The output can be turned on via the
debug_level module parameter (which can also be set after
the driver is loaded through sysfs).

View File

@ -1,7 +1,3 @@
ifdef CONFIG_INFINIBAND_MTHCA_DEBUG
EXTRA_CFLAGS += -DDEBUG
endif
obj-$(CONFIG_INFINIBAND_MTHCA) += ib_mthca.o
ib_mthca-y := mthca_main.o mthca_cmd.o mthca_profile.o mthca_reset.o \

View File

@ -42,6 +42,20 @@
#include "mthca_dev.h"
enum {
MTHCA_RATE_TAVOR_FULL = 0,
MTHCA_RATE_TAVOR_1X = 1,
MTHCA_RATE_TAVOR_4X = 2,
MTHCA_RATE_TAVOR_1X_DDR = 3
};
enum {
MTHCA_RATE_MEMFREE_FULL = 0,
MTHCA_RATE_MEMFREE_QUARTER = 1,
MTHCA_RATE_MEMFREE_EIGHTH = 2,
MTHCA_RATE_MEMFREE_HALF = 3
};
struct mthca_av {
__be32 port_pd;
u8 reserved1;
@ -55,6 +69,90 @@ struct mthca_av {
__be32 dgid[4];
};
static enum ib_rate memfree_rate_to_ib(u8 mthca_rate, u8 port_rate)
{
switch (mthca_rate) {
case MTHCA_RATE_MEMFREE_EIGHTH:
return mult_to_ib_rate(port_rate >> 3);
case MTHCA_RATE_MEMFREE_QUARTER:
return mult_to_ib_rate(port_rate >> 2);
case MTHCA_RATE_MEMFREE_HALF:
return mult_to_ib_rate(port_rate >> 1);
case MTHCA_RATE_MEMFREE_FULL:
default:
return mult_to_ib_rate(port_rate);
}
}
static enum ib_rate tavor_rate_to_ib(u8 mthca_rate, u8 port_rate)
{
switch (mthca_rate) {
case MTHCA_RATE_TAVOR_1X: return IB_RATE_2_5_GBPS;
case MTHCA_RATE_TAVOR_1X_DDR: return IB_RATE_5_GBPS;
case MTHCA_RATE_TAVOR_4X: return IB_RATE_10_GBPS;
default: return port_rate;
}
}
enum ib_rate mthca_rate_to_ib(struct mthca_dev *dev, u8 mthca_rate, u8 port)
{
if (mthca_is_memfree(dev)) {
/* Handle old Arbel FW */
if (dev->limits.stat_rate_support == 0x3 && mthca_rate)
return IB_RATE_2_5_GBPS;
return memfree_rate_to_ib(mthca_rate, dev->rate[port - 1]);
} else
return tavor_rate_to_ib(mthca_rate, dev->rate[port - 1]);
}
static u8 ib_rate_to_memfree(u8 req_rate, u8 cur_rate)
{
if (cur_rate <= req_rate)
return 0;
/*
* Inter-packet delay (IPD) to get from rate X down to a rate
* no more than Y is (X - 1) / Y.
*/
switch ((cur_rate - 1) / req_rate) {
case 0: return MTHCA_RATE_MEMFREE_FULL;
case 1: return MTHCA_RATE_MEMFREE_HALF;
case 2: /* fall through */
case 3: return MTHCA_RATE_MEMFREE_QUARTER;
default: return MTHCA_RATE_MEMFREE_EIGHTH;
}
}
static u8 ib_rate_to_tavor(u8 static_rate)
{
switch (static_rate) {
case IB_RATE_2_5_GBPS: return MTHCA_RATE_TAVOR_1X;
case IB_RATE_5_GBPS: return MTHCA_RATE_TAVOR_1X_DDR;
case IB_RATE_10_GBPS: return MTHCA_RATE_TAVOR_4X;
default: return MTHCA_RATE_TAVOR_FULL;
}
}
u8 mthca_get_rate(struct mthca_dev *dev, int static_rate, u8 port)
{
u8 rate;
if (!static_rate || ib_rate_to_mult(static_rate) >= dev->rate[port - 1])
return 0;
if (mthca_is_memfree(dev))
rate = ib_rate_to_memfree(ib_rate_to_mult(static_rate),
dev->rate[port - 1]);
else
rate = ib_rate_to_tavor(static_rate);
if (!(dev->limits.stat_rate_support & (1 << rate)))
rate = 1;
return rate;
}
int mthca_create_ah(struct mthca_dev *dev,
struct mthca_pd *pd,
struct ib_ah_attr *ah_attr,
@ -107,7 +205,7 @@ on_hca_fail:
av->g_slid = ah_attr->src_path_bits;
av->dlid = cpu_to_be16(ah_attr->dlid);
av->msg_sr = (3 << 4) | /* 2K message */
ah_attr->static_rate;
mthca_get_rate(dev, ah_attr->static_rate, ah_attr->port_num);
av->sl_tclass_flowlabel = cpu_to_be32(ah_attr->sl << 28);
if (ah_attr->ah_flags & IB_AH_GRH) {
av->g_slid |= 0x80;

View File

@ -965,6 +965,7 @@ int mthca_QUERY_DEV_LIM(struct mthca_dev *dev,
u32 *outbox;
u8 field;
u16 size;
u16 stat_rate;
int err;
#define QUERY_DEV_LIM_OUT_SIZE 0x100
@ -995,6 +996,7 @@ int mthca_QUERY_DEV_LIM(struct mthca_dev *dev,
#define QUERY_DEV_LIM_MTU_WIDTH_OFFSET 0x36
#define QUERY_DEV_LIM_VL_PORT_OFFSET 0x37
#define QUERY_DEV_LIM_MAX_GID_OFFSET 0x3b
#define QUERY_DEV_LIM_RATE_SUPPORT_OFFSET 0x3c
#define QUERY_DEV_LIM_MAX_PKEY_OFFSET 0x3f
#define QUERY_DEV_LIM_FLAGS_OFFSET 0x44
#define QUERY_DEV_LIM_RSVD_UAR_OFFSET 0x48
@ -1086,6 +1088,8 @@ int mthca_QUERY_DEV_LIM(struct mthca_dev *dev,
dev_lim->num_ports = field & 0xf;
MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_GID_OFFSET);
dev_lim->max_gids = 1 << (field & 0xf);
MTHCA_GET(stat_rate, outbox, QUERY_DEV_LIM_RATE_SUPPORT_OFFSET);
dev_lim->stat_rate_support = stat_rate;
MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_PKEY_OFFSET);
dev_lim->max_pkeys = 1 << (field & 0xf);
MTHCA_GET(dev_lim->flags, outbox, QUERY_DEV_LIM_FLAGS_OFFSET);

View File

@ -146,6 +146,7 @@ struct mthca_dev_lim {
int max_vl;
int num_ports;
int max_gids;
u16 stat_rate_support;
int max_pkeys;
u32 flags;
int reserved_uars;

View File

@ -151,6 +151,7 @@ struct mthca_limits {
int reserved_qps;
int num_srqs;
int max_srq_wqes;
int max_srq_sge;
int reserved_srqs;
int num_eecs;
int reserved_eecs;
@ -172,6 +173,7 @@ struct mthca_limits {
int reserved_pds;
u32 page_size_cap;
u32 flags;
u16 stat_rate_support;
u8 port_width_cap;
};
@ -353,10 +355,24 @@ struct mthca_dev {
struct ib_mad_agent *send_agent[MTHCA_MAX_PORTS][2];
struct ib_ah *sm_ah[MTHCA_MAX_PORTS];
spinlock_t sm_lock;
u8 rate[MTHCA_MAX_PORTS];
};
#define mthca_dbg(mdev, format, arg...) \
dev_dbg(&mdev->pdev->dev, format, ## arg)
#ifdef CONFIG_INFINIBAND_MTHCA_DEBUG
extern int mthca_debug_level;
#define mthca_dbg(mdev, format, arg...) \
do { \
if (mthca_debug_level) \
dev_printk(KERN_DEBUG, &mdev->pdev->dev, format, ## arg); \
} while (0)
#else /* CONFIG_INFINIBAND_MTHCA_DEBUG */
#define mthca_dbg(mdev, format, arg...) do { (void) mdev; } while (0)
#endif /* CONFIG_INFINIBAND_MTHCA_DEBUG */
#define mthca_err(mdev, format, arg...) \
dev_err(&mdev->pdev->dev, format, ## arg)
#define mthca_info(mdev, format, arg...) \
@ -492,6 +508,7 @@ void mthca_free_srq(struct mthca_dev *dev, struct mthca_srq *srq);
int mthca_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr,
enum ib_srq_attr_mask attr_mask);
int mthca_query_srq(struct ib_srq *srq, struct ib_srq_attr *srq_attr);
int mthca_max_srq_sge(struct mthca_dev *dev);
void mthca_srq_event(struct mthca_dev *dev, u32 srqn,
enum ib_event_type event_type);
void mthca_free_srq_wqe(struct mthca_srq *srq, u32 wqe_addr);
@ -542,6 +559,8 @@ int mthca_read_ah(struct mthca_dev *dev, struct mthca_ah *ah,
struct ib_ud_header *header);
int mthca_ah_query(struct ib_ah *ibah, struct ib_ah_attr *attr);
int mthca_ah_grh_present(struct mthca_ah *ah);
u8 mthca_get_rate(struct mthca_dev *dev, int static_rate, u8 port);
enum ib_rate mthca_rate_to_ib(struct mthca_dev *dev, u8 mthca_rate, u8 port);
int mthca_multicast_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid);
int mthca_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid);

View File

@ -49,6 +49,30 @@ enum {
MTHCA_VENDOR_CLASS2 = 0xa
};
int mthca_update_rate(struct mthca_dev *dev, u8 port_num)
{
struct ib_port_attr *tprops = NULL;
int ret;
tprops = kmalloc(sizeof *tprops, GFP_KERNEL);
if (!tprops)
return -ENOMEM;
ret = ib_query_port(&dev->ib_dev, port_num, tprops);
if (ret) {
printk(KERN_WARNING "ib_query_port failed (%d) for %s port %d\n",
ret, dev->ib_dev.name, port_num);
goto out;
}
dev->rate[port_num - 1] = tprops->active_speed *
ib_width_enum_to_int(tprops->active_width);
out:
kfree(tprops);
return ret;
}
static void update_sm_ah(struct mthca_dev *dev,
u8 port_num, u16 lid, u8 sl)
{
@ -90,6 +114,7 @@ static void smp_snoop(struct ib_device *ibdev,
mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE) &&
mad->mad_hdr.method == IB_MGMT_METHOD_SET) {
if (mad->mad_hdr.attr_id == IB_SMP_ATTR_PORT_INFO) {
mthca_update_rate(to_mdev(ibdev), port_num);
update_sm_ah(to_mdev(ibdev), port_num,
be16_to_cpup((__be16 *) (mad->data + 58)),
(*(u8 *) (mad->data + 76)) & 0xf);
@ -246,6 +271,7 @@ int mthca_create_agents(struct mthca_dev *dev)
{
struct ib_mad_agent *agent;
int p, q;
int ret;
spin_lock_init(&dev->sm_lock);
@ -255,11 +281,23 @@ int mthca_create_agents(struct mthca_dev *dev)
q ? IB_QPT_GSI : IB_QPT_SMI,
NULL, 0, send_handler,
NULL, NULL);
if (IS_ERR(agent))
if (IS_ERR(agent)) {
ret = PTR_ERR(agent);
goto err;
}
dev->send_agent[p][q] = agent;
}
for (p = 1; p <= dev->limits.num_ports; ++p) {
ret = mthca_update_rate(dev, p);
if (ret) {
mthca_err(dev, "Failed to obtain port %d rate."
" aborting.\n", p);
goto err;
}
}
return 0;
err:
@ -268,7 +306,7 @@ err:
if (dev->send_agent[p][q])
ib_unregister_mad_agent(dev->send_agent[p][q]);
return PTR_ERR(agent);
return ret;
}
void __devexit mthca_free_agents(struct mthca_dev *dev)

View File

@ -52,6 +52,14 @@ MODULE_DESCRIPTION("Mellanox InfiniBand HCA low-level driver");
MODULE_LICENSE("Dual BSD/GPL");
MODULE_VERSION(DRV_VERSION);
#ifdef CONFIG_INFINIBAND_MTHCA_DEBUG
int mthca_debug_level = 0;
module_param_named(debug_level, mthca_debug_level, int, 0644);
MODULE_PARM_DESC(debug_level, "Enable debug tracing if > 0");
#endif /* CONFIG_INFINIBAND_MTHCA_DEBUG */
#ifdef CONFIG_PCI_MSI
static int msi_x = 0;
@ -69,6 +77,10 @@ MODULE_PARM_DESC(msi, "attempt to use MSI if nonzero");
#endif /* CONFIG_PCI_MSI */
static int tune_pci = 0;
module_param(tune_pci, int, 0444);
MODULE_PARM_DESC(tune_pci, "increase PCI burst from the default set by BIOS if nonzero");
static const char mthca_version[] __devinitdata =
DRV_NAME ": Mellanox InfiniBand HCA driver v"
DRV_VERSION " (" DRV_RELDATE ")\n";
@ -90,6 +102,9 @@ static int __devinit mthca_tune_pci(struct mthca_dev *mdev)
int cap;
u16 val;
if (!tune_pci)
return 0;
/* First try to max out Read Byte Count */
cap = pci_find_capability(mdev->pdev, PCI_CAP_ID_PCIX);
if (cap) {
@ -176,6 +191,7 @@ static int __devinit mthca_dev_lim(struct mthca_dev *mdev, struct mthca_dev_lim
mdev->limits.reserved_srqs = dev_lim->reserved_srqs;
mdev->limits.reserved_eecs = dev_lim->reserved_eecs;
mdev->limits.max_desc_sz = dev_lim->max_desc_sz;
mdev->limits.max_srq_sge = mthca_max_srq_sge(mdev);
/*
* Subtract 1 from the limit because we need to allocate a
* spare CQE so the HCA HW can tell the difference between an
@ -191,6 +207,18 @@ static int __devinit mthca_dev_lim(struct mthca_dev *mdev, struct mthca_dev_lim
mdev->limits.port_width_cap = dev_lim->max_port_width;
mdev->limits.page_size_cap = ~(u32) (dev_lim->min_page_sz - 1);
mdev->limits.flags = dev_lim->flags;
/*
* For old FW that doesn't return static rate support, use a
* value of 0x3 (only static rate values of 0 or 1 are handled),
* except on Sinai, where even old FW can handle static rate
* values of 2 and 3.
*/
if (dev_lim->stat_rate_support)
mdev->limits.stat_rate_support = dev_lim->stat_rate_support;
else if (mdev->mthca_flags & MTHCA_FLAG_SINAI_OPT)
mdev->limits.stat_rate_support = 0xf;
else
mdev->limits.stat_rate_support = 0x3;
/* IB_DEVICE_RESIZE_MAX_WR not supported by driver.
May be doable since hardware supports it for SRQ.

View File

@ -106,7 +106,7 @@ static int mthca_query_device(struct ib_device *ibdev,
props->max_res_rd_atom = props->max_qp_rd_atom * props->max_qp;
props->max_srq = mdev->limits.num_srqs - mdev->limits.reserved_srqs;
props->max_srq_wr = mdev->limits.max_srq_wqes;
props->max_srq_sge = mdev->limits.max_sg;
props->max_srq_sge = mdev->limits.max_srq_sge;
props->local_ca_ack_delay = mdev->limits.local_ca_ack_delay;
props->atomic_cap = mdev->limits.flags & DEV_LIM_FLAG_ATOMIC ?
IB_ATOMIC_HCA : IB_ATOMIC_NONE;

View File

@ -257,6 +257,8 @@ struct mthca_qp {
atomic_t refcount;
u32 qpn;
int is_direct;
u8 port; /* for SQP and memfree use only */
u8 alt_port; /* for memfree use only */
u8 transport;
u8 state;
u8 atomic_rd_en;
@ -278,7 +280,6 @@ struct mthca_qp {
struct mthca_sqp {
struct mthca_qp qp;
int port;
int pkey_index;
u32 qkey;
u32 send_psn;

View File

@ -248,6 +248,9 @@ void mthca_qp_event(struct mthca_dev *dev, u32 qpn,
return;
}
if (event_type == IB_EVENT_PATH_MIG)
qp->port = qp->alt_port;
event.device = &dev->ib_dev;
event.event = event_type;
event.element.qp = &qp->ibqp;
@ -392,10 +395,16 @@ static void to_ib_ah_attr(struct mthca_dev *dev, struct ib_ah_attr *ib_ah_attr,
{
memset(ib_ah_attr, 0, sizeof *path);
ib_ah_attr->port_num = (be32_to_cpu(path->port_pkey) >> 24) & 0x3;
if (ib_ah_attr->port_num == 0 || ib_ah_attr->port_num > dev->limits.num_ports)
return;
ib_ah_attr->dlid = be16_to_cpu(path->rlid);
ib_ah_attr->sl = be32_to_cpu(path->sl_tclass_flowlabel) >> 28;
ib_ah_attr->src_path_bits = path->g_mylmc & 0x7f;
ib_ah_attr->static_rate = path->static_rate & 0x7;
ib_ah_attr->static_rate = mthca_rate_to_ib(dev,
path->static_rate & 0x7,
ib_ah_attr->port_num);
ib_ah_attr->ah_flags = (path->g_mylmc & (1 << 7)) ? IB_AH_GRH : 0;
if (ib_ah_attr->ah_flags) {
ib_ah_attr->grh.sgid_index = path->mgid_index & (dev->limits.gid_table_len - 1);
@ -455,8 +464,10 @@ int mthca_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *qp_attr, int qp_attr_m
qp_attr->cap.max_recv_sge = qp->rq.max_gs;
qp_attr->cap.max_inline_data = qp->max_inline_data;
to_ib_ah_attr(dev, &qp_attr->ah_attr, &context->pri_path);
to_ib_ah_attr(dev, &qp_attr->alt_ah_attr, &context->alt_path);
if (qp->transport == RC || qp->transport == UC) {
to_ib_ah_attr(dev, &qp_attr->ah_attr, &context->pri_path);
to_ib_ah_attr(dev, &qp_attr->alt_ah_attr, &context->alt_path);
}
qp_attr->pkey_index = be32_to_cpu(context->pri_path.port_pkey) & 0x7f;
qp_attr->alt_pkey_index = be32_to_cpu(context->alt_path.port_pkey) & 0x7f;
@ -484,11 +495,11 @@ out:
}
static int mthca_path_set(struct mthca_dev *dev, struct ib_ah_attr *ah,
struct mthca_qp_path *path)
struct mthca_qp_path *path, u8 port)
{
path->g_mylmc = ah->src_path_bits & 0x7f;
path->rlid = cpu_to_be16(ah->dlid);
path->static_rate = !!ah->static_rate;
path->static_rate = mthca_get_rate(dev, ah->static_rate, port);
if (ah->ah_flags & IB_AH_GRH) {
if (ah->grh.sgid_index >= dev->limits.gid_table_len) {
@ -634,7 +645,7 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask)
if (qp->transport == MLX)
qp_context->pri_path.port_pkey |=
cpu_to_be32(to_msqp(qp)->port << 24);
cpu_to_be32(qp->port << 24);
else {
if (attr_mask & IB_QP_PORT) {
qp_context->pri_path.port_pkey |=
@ -657,7 +668,8 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask)
}
if (attr_mask & IB_QP_AV) {
if (mthca_path_set(dev, &attr->ah_attr, &qp_context->pri_path))
if (mthca_path_set(dev, &attr->ah_attr, &qp_context->pri_path,
attr_mask & IB_QP_PORT ? attr->port_num : qp->port))
return -EINVAL;
qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_PRIMARY_ADDR_PATH);
@ -681,7 +693,8 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask)
return -EINVAL;
}
if (mthca_path_set(dev, &attr->alt_ah_attr, &qp_context->alt_path))
if (mthca_path_set(dev, &attr->alt_ah_attr, &qp_context->alt_path,
attr->alt_ah_attr.port_num))
return -EINVAL;
qp_context->alt_path.port_pkey |= cpu_to_be32(attr->alt_pkey_index |
@ -791,6 +804,10 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask)
qp->atomic_rd_en = attr->qp_access_flags;
if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC)
qp->resp_depth = attr->max_dest_rd_atomic;
if (attr_mask & IB_QP_PORT)
qp->port = attr->port_num;
if (attr_mask & IB_QP_ALT_PATH)
qp->alt_port = attr->alt_port_num;
if (is_sqp(dev, qp))
store_attrs(to_msqp(qp), attr, attr_mask);
@ -802,13 +819,13 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask)
if (is_qp0(dev, qp)) {
if (cur_state != IB_QPS_RTR &&
new_state == IB_QPS_RTR)
init_port(dev, to_msqp(qp)->port);
init_port(dev, qp->port);
if (cur_state != IB_QPS_RESET &&
cur_state != IB_QPS_ERR &&
(new_state == IB_QPS_RESET ||
new_state == IB_QPS_ERR))
mthca_CLOSE_IB(dev, to_msqp(qp)->port, &status);
mthca_CLOSE_IB(dev, qp->port, &status);
}
/*
@ -1212,6 +1229,9 @@ int mthca_alloc_qp(struct mthca_dev *dev,
if (qp->qpn == -1)
return -ENOMEM;
/* initialize port to zero for error-catching. */
qp->port = 0;
err = mthca_alloc_qp_common(dev, pd, send_cq, recv_cq,
send_policy, qp);
if (err) {
@ -1261,7 +1281,7 @@ int mthca_alloc_sqp(struct mthca_dev *dev,
if (err)
goto err_out;
sqp->port = port;
sqp->qp.port = port;
sqp->qp.qpn = mqpn;
sqp->qp.transport = MLX;
@ -1404,10 +1424,10 @@ static int build_mlx_header(struct mthca_dev *dev, struct mthca_sqp *sqp,
sqp->ud_header.lrh.source_lid = IB_LID_PERMISSIVE;
sqp->ud_header.bth.solicited_event = !!(wr->send_flags & IB_SEND_SOLICITED);
if (!sqp->qp.ibqp.qp_num)
ib_get_cached_pkey(&dev->ib_dev, sqp->port,
ib_get_cached_pkey(&dev->ib_dev, sqp->qp.port,
sqp->pkey_index, &pkey);
else
ib_get_cached_pkey(&dev->ib_dev, sqp->port,
ib_get_cached_pkey(&dev->ib_dev, sqp->qp.port,
wr->wr.ud.pkey_index, &pkey);
sqp->ud_header.bth.pkey = cpu_to_be16(pkey);
sqp->ud_header.bth.destination_qpn = cpu_to_be32(wr->wr.ud.remote_qpn);

View File

@ -192,7 +192,7 @@ int mthca_alloc_srq(struct mthca_dev *dev, struct mthca_pd *pd,
/* Sanity check SRQ size before proceeding */
if (attr->max_wr > dev->limits.max_srq_wqes ||
attr->max_sge > dev->limits.max_sg)
attr->max_sge > dev->limits.max_srq_sge)
return -EINVAL;
srq->max = attr->max_wr;
@ -660,6 +660,31 @@ int mthca_arbel_post_srq_recv(struct ib_srq *ibsrq, struct ib_recv_wr *wr,
return err;
}
int mthca_max_srq_sge(struct mthca_dev *dev)
{
if (mthca_is_memfree(dev))
return dev->limits.max_sg;
/*
* SRQ allocations are based on powers of 2 for Tavor,
* (although they only need to be multiples of 16 bytes).
*
* Therefore, we need to base the max number of sg entries on
* the largest power of 2 descriptor size that is <= to the
* actual max WQE descriptor size, rather than return the
* max_sg value given by the firmware (which is based on WQE
* sizes as multiples of 16, not powers of 2).
*
* If SRQ implementation is changed for Tavor to be based on
* multiples of 16, the calculation below can be deleted and
* the FW max_sg value returned.
*/
return min_t(int, dev->limits.max_sg,
((1 << (fls(dev->limits.max_desc_sz) - 1)) -
sizeof (struct mthca_next_seg)) /
sizeof (struct mthca_data_seg));
}
int __devinit mthca_init_srq_table(struct mthca_dev *dev)
{
int err;

View File

@ -10,8 +10,9 @@ config INFINIBAND_IPOIB
group: <http://www.ietf.org/html.charters/ipoib-charter.html>.
config INFINIBAND_IPOIB_DEBUG
bool "IP-over-InfiniBand debugging"
bool "IP-over-InfiniBand debugging" if EMBEDDED
depends on INFINIBAND_IPOIB
default y
---help---
This option causes debugging code to be compiled into the
IPoIB driver. The output can be turned on via the

View File

@ -65,6 +65,8 @@ enum {
IPOIB_RX_RING_SIZE = 128,
IPOIB_TX_RING_SIZE = 64,
IPOIB_MAX_QUEUE_SIZE = 8192,
IPOIB_MIN_QUEUE_SIZE = 2,
IPOIB_NUM_WC = 4,
@ -230,6 +232,9 @@ static inline struct ipoib_neigh **to_ipoib_neigh(struct neighbour *neigh)
INFINIBAND_ALEN, sizeof(void *));
}
struct ipoib_neigh *ipoib_neigh_alloc(struct neighbour *neigh);
void ipoib_neigh_free(struct ipoib_neigh *neigh);
extern struct workqueue_struct *ipoib_workqueue;
/* functions */
@ -329,6 +334,8 @@ static inline void ipoib_unregister_debugfs(void) { }
#define ipoib_warn(priv, format, arg...) \
ipoib_printk(KERN_WARNING, priv, format , ## arg)
extern int ipoib_sendq_size;
extern int ipoib_recvq_size;
#ifdef CONFIG_INFINIBAND_IPOIB_DEBUG
extern int ipoib_debug_level;

View File

@ -213,7 +213,7 @@ static int ipoib_path_seq_show(struct seq_file *file, void *iter_ptr)
gid_buf, path.pathrec.dlid ? "yes" : "no");
if (path.pathrec.dlid) {
rate = ib_sa_rate_enum_to_int(path.pathrec.rate) * 25;
rate = ib_rate_to_mult(path.pathrec.rate) * 25;
seq_printf(file,
" DLID: 0x%04x\n"

View File

@ -161,7 +161,7 @@ static int ipoib_ib_post_receives(struct net_device *dev)
struct ipoib_dev_priv *priv = netdev_priv(dev);
int i;
for (i = 0; i < IPOIB_RX_RING_SIZE; ++i) {
for (i = 0; i < ipoib_recvq_size; ++i) {
if (ipoib_alloc_rx_skb(dev, i)) {
ipoib_warn(priv, "failed to allocate receive buffer %d\n", i);
return -ENOMEM;
@ -187,7 +187,7 @@ static void ipoib_ib_handle_wc(struct net_device *dev,
if (wr_id & IPOIB_OP_RECV) {
wr_id &= ~IPOIB_OP_RECV;
if (wr_id < IPOIB_RX_RING_SIZE) {
if (wr_id < ipoib_recvq_size) {
struct sk_buff *skb = priv->rx_ring[wr_id].skb;
dma_addr_t addr = priv->rx_ring[wr_id].mapping;
@ -252,9 +252,9 @@ static void ipoib_ib_handle_wc(struct net_device *dev,
struct ipoib_tx_buf *tx_req;
unsigned long flags;
if (wr_id >= IPOIB_TX_RING_SIZE) {
if (wr_id >= ipoib_sendq_size) {
ipoib_warn(priv, "completion event with wrid %d (> %d)\n",
wr_id, IPOIB_TX_RING_SIZE);
wr_id, ipoib_sendq_size);
return;
}
@ -275,7 +275,7 @@ static void ipoib_ib_handle_wc(struct net_device *dev,
spin_lock_irqsave(&priv->tx_lock, flags);
++priv->tx_tail;
if (netif_queue_stopped(dev) &&
priv->tx_head - priv->tx_tail <= IPOIB_TX_RING_SIZE / 2)
priv->tx_head - priv->tx_tail <= ipoib_sendq_size >> 1)
netif_wake_queue(dev);
spin_unlock_irqrestore(&priv->tx_lock, flags);
@ -344,13 +344,13 @@ void ipoib_send(struct net_device *dev, struct sk_buff *skb,
* means we have to make sure everything is properly recorded and
* our state is consistent before we call post_send().
*/
tx_req = &priv->tx_ring[priv->tx_head & (IPOIB_TX_RING_SIZE - 1)];
tx_req = &priv->tx_ring[priv->tx_head & (ipoib_sendq_size - 1)];
tx_req->skb = skb;
addr = dma_map_single(priv->ca->dma_device, skb->data, skb->len,
DMA_TO_DEVICE);
pci_unmap_addr_set(tx_req, mapping, addr);
if (unlikely(post_send(priv, priv->tx_head & (IPOIB_TX_RING_SIZE - 1),
if (unlikely(post_send(priv, priv->tx_head & (ipoib_sendq_size - 1),
address->ah, qpn, addr, skb->len))) {
ipoib_warn(priv, "post_send failed\n");
++priv->stats.tx_errors;
@ -363,7 +363,7 @@ void ipoib_send(struct net_device *dev, struct sk_buff *skb,
address->last_send = priv->tx_head;
++priv->tx_head;
if (priv->tx_head - priv->tx_tail == IPOIB_TX_RING_SIZE) {
if (priv->tx_head - priv->tx_tail == ipoib_sendq_size) {
ipoib_dbg(priv, "TX ring full, stopping kernel net queue\n");
netif_stop_queue(dev);
}
@ -488,7 +488,7 @@ static int recvs_pending(struct net_device *dev)
int pending = 0;
int i;
for (i = 0; i < IPOIB_RX_RING_SIZE; ++i)
for (i = 0; i < ipoib_recvq_size; ++i)
if (priv->rx_ring[i].skb)
++pending;
@ -527,7 +527,7 @@ int ipoib_ib_dev_stop(struct net_device *dev)
*/
while ((int) priv->tx_tail - (int) priv->tx_head < 0) {
tx_req = &priv->tx_ring[priv->tx_tail &
(IPOIB_TX_RING_SIZE - 1)];
(ipoib_sendq_size - 1)];
dma_unmap_single(priv->ca->dma_device,
pci_unmap_addr(tx_req, mapping),
tx_req->skb->len,
@ -536,7 +536,7 @@ int ipoib_ib_dev_stop(struct net_device *dev)
++priv->tx_tail;
}
for (i = 0; i < IPOIB_RX_RING_SIZE; ++i)
for (i = 0; i < ipoib_recvq_size; ++i)
if (priv->rx_ring[i].skb) {
dma_unmap_single(priv->ca->dma_device,
pci_unmap_addr(&priv->rx_ring[i],

View File

@ -41,6 +41,7 @@
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/kernel.h>
#include <linux/if_arp.h> /* For ARPHRD_xxx */
@ -53,6 +54,14 @@ MODULE_AUTHOR("Roland Dreier");
MODULE_DESCRIPTION("IP-over-InfiniBand net driver");
MODULE_LICENSE("Dual BSD/GPL");
int ipoib_sendq_size __read_mostly = IPOIB_TX_RING_SIZE;
int ipoib_recvq_size __read_mostly = IPOIB_RX_RING_SIZE;
module_param_named(send_queue_size, ipoib_sendq_size, int, 0444);
MODULE_PARM_DESC(send_queue_size, "Number of descriptors in send queue");
module_param_named(recv_queue_size, ipoib_recvq_size, int, 0444);
MODULE_PARM_DESC(recv_queue_size, "Number of descriptors in receive queue");
#ifdef CONFIG_INFINIBAND_IPOIB_DEBUG
int ipoib_debug_level;
@ -252,8 +261,8 @@ static void path_free(struct net_device *dev, struct ipoib_path *path)
*/
if (neigh->ah)
ipoib_put_ah(neigh->ah);
*to_ipoib_neigh(neigh->neighbour) = NULL;
kfree(neigh);
ipoib_neigh_free(neigh);
}
spin_unlock_irqrestore(&priv->lock, flags);
@ -327,9 +336,8 @@ void ipoib_flush_paths(struct net_device *dev)
struct ipoib_dev_priv *priv = netdev_priv(dev);
struct ipoib_path *path, *tp;
LIST_HEAD(remove_list);
unsigned long flags;
spin_lock_irqsave(&priv->lock, flags);
spin_lock_irq(&priv->lock);
list_splice(&priv->path_list, &remove_list);
INIT_LIST_HEAD(&priv->path_list);
@ -337,14 +345,15 @@ void ipoib_flush_paths(struct net_device *dev)
list_for_each_entry(path, &remove_list, list)
rb_erase(&path->rb_node, &priv->path_tree);
spin_unlock_irqrestore(&priv->lock, flags);
list_for_each_entry_safe(path, tp, &remove_list, list) {
if (path->query)
ib_sa_cancel_query(path->query_id, path->query);
spin_unlock_irq(&priv->lock);
wait_for_completion(&path->done);
path_free(dev, path);
spin_lock_irq(&priv->lock);
}
spin_unlock_irq(&priv->lock);
}
static void path_rec_completion(int status,
@ -373,16 +382,9 @@ static void path_rec_completion(int status,
struct ib_ah_attr av = {
.dlid = be16_to_cpu(pathrec->dlid),
.sl = pathrec->sl,
.port_num = priv->port
.port_num = priv->port,
.static_rate = pathrec->rate
};
int path_rate = ib_sa_rate_enum_to_int(pathrec->rate);
if (path_rate > 0 && priv->local_rate > path_rate)
av.static_rate = (priv->local_rate - 1) / path_rate;
ipoib_dbg(priv, "static_rate %d for local port %dX, path %dX\n",
av.static_rate, priv->local_rate,
ib_sa_rate_enum_to_int(pathrec->rate));
ah = ipoib_create_ah(dev, priv->pd, &av);
}
@ -481,7 +483,7 @@ static void neigh_add_path(struct sk_buff *skb, struct net_device *dev)
struct ipoib_path *path;
struct ipoib_neigh *neigh;
neigh = kmalloc(sizeof *neigh, GFP_ATOMIC);
neigh = ipoib_neigh_alloc(skb->dst->neighbour);
if (!neigh) {
++priv->stats.tx_dropped;
dev_kfree_skb_any(skb);
@ -489,8 +491,6 @@ static void neigh_add_path(struct sk_buff *skb, struct net_device *dev)
}
skb_queue_head_init(&neigh->queue);
neigh->neighbour = skb->dst->neighbour;
*to_ipoib_neigh(skb->dst->neighbour) = neigh;
/*
* We can only be called from ipoib_start_xmit, so we're
@ -503,7 +503,7 @@ static void neigh_add_path(struct sk_buff *skb, struct net_device *dev)
path = path_rec_create(dev,
(union ib_gid *) (skb->dst->neighbour->ha + 4));
if (!path)
goto err;
goto err_path;
__path_add(dev, path);
}
@ -521,17 +521,17 @@ static void neigh_add_path(struct sk_buff *skb, struct net_device *dev)
__skb_queue_tail(&neigh->queue, skb);
if (!path->query && path_rec_start(dev, path))
goto err;
goto err_list;
}
spin_unlock(&priv->lock);
return;
err:
*to_ipoib_neigh(skb->dst->neighbour) = NULL;
err_list:
list_del(&neigh->list);
kfree(neigh);
err_path:
ipoib_neigh_free(neigh);
++priv->stats.tx_dropped;
dev_kfree_skb_any(skb);
@ -763,8 +763,7 @@ static void ipoib_neigh_destructor(struct neighbour *n)
if (neigh->ah)
ah = neigh->ah;
list_del(&neigh->list);
*to_ipoib_neigh(n) = NULL;
kfree(neigh);
ipoib_neigh_free(neigh);
}
spin_unlock_irqrestore(&priv->lock, flags);
@ -773,6 +772,26 @@ static void ipoib_neigh_destructor(struct neighbour *n)
ipoib_put_ah(ah);
}
struct ipoib_neigh *ipoib_neigh_alloc(struct neighbour *neighbour)
{
struct ipoib_neigh *neigh;
neigh = kmalloc(sizeof *neigh, GFP_ATOMIC);
if (!neigh)
return NULL;
neigh->neighbour = neighbour;
*to_ipoib_neigh(neighbour) = neigh;
return neigh;
}
void ipoib_neigh_free(struct ipoib_neigh *neigh)
{
*to_ipoib_neigh(neigh->neighbour) = NULL;
kfree(neigh);
}
static int ipoib_neigh_setup_dev(struct net_device *dev, struct neigh_parms *parms)
{
parms->neigh_destructor = ipoib_neigh_destructor;
@ -785,20 +804,19 @@ int ipoib_dev_init(struct net_device *dev, struct ib_device *ca, int port)
struct ipoib_dev_priv *priv = netdev_priv(dev);
/* Allocate RX/TX "rings" to hold queued skbs */
priv->rx_ring = kzalloc(IPOIB_RX_RING_SIZE * sizeof (struct ipoib_rx_buf),
priv->rx_ring = kzalloc(ipoib_recvq_size * sizeof *priv->rx_ring,
GFP_KERNEL);
if (!priv->rx_ring) {
printk(KERN_WARNING "%s: failed to allocate RX ring (%d entries)\n",
ca->name, IPOIB_RX_RING_SIZE);
ca->name, ipoib_recvq_size);
goto out;
}
priv->tx_ring = kzalloc(IPOIB_TX_RING_SIZE * sizeof (struct ipoib_tx_buf),
priv->tx_ring = kzalloc(ipoib_sendq_size * sizeof *priv->tx_ring,
GFP_KERNEL);
if (!priv->tx_ring) {
printk(KERN_WARNING "%s: failed to allocate TX ring (%d entries)\n",
ca->name, IPOIB_TX_RING_SIZE);
ca->name, ipoib_sendq_size);
goto out_rx_ring_cleanup;
}
@ -866,7 +884,7 @@ static void ipoib_setup(struct net_device *dev)
dev->hard_header_len = IPOIB_ENCAP_LEN + INFINIBAND_ALEN;
dev->addr_len = INFINIBAND_ALEN;
dev->type = ARPHRD_INFINIBAND;
dev->tx_queue_len = IPOIB_TX_RING_SIZE * 2;
dev->tx_queue_len = ipoib_sendq_size * 2;
dev->features = NETIF_F_VLAN_CHALLENGED | NETIF_F_LLTX;
/* MTU will be reset when mcast join happens */
@ -1118,6 +1136,14 @@ static int __init ipoib_init_module(void)
{
int ret;
ipoib_recvq_size = roundup_pow_of_two(ipoib_recvq_size);
ipoib_recvq_size = min(ipoib_recvq_size, IPOIB_MAX_QUEUE_SIZE);
ipoib_recvq_size = max(ipoib_recvq_size, IPOIB_MIN_QUEUE_SIZE);
ipoib_sendq_size = roundup_pow_of_two(ipoib_sendq_size);
ipoib_sendq_size = min(ipoib_sendq_size, IPOIB_MAX_QUEUE_SIZE);
ipoib_sendq_size = max(ipoib_sendq_size, IPOIB_MIN_QUEUE_SIZE);
ret = ipoib_register_debugfs();
if (ret)
return ret;

View File

@ -114,8 +114,7 @@ static void ipoib_mcast_free(struct ipoib_mcast *mcast)
*/
if (neigh->ah)
ipoib_put_ah(neigh->ah);
*to_ipoib_neigh(neigh->neighbour) = NULL;
kfree(neigh);
ipoib_neigh_free(neigh);
}
spin_unlock_irqrestore(&priv->lock, flags);
@ -251,6 +250,7 @@ static int ipoib_mcast_join_finish(struct ipoib_mcast *mcast,
.port_num = priv->port,
.sl = mcast->mcmember.sl,
.ah_flags = IB_AH_GRH,
.static_rate = mcast->mcmember.rate,
.grh = {
.flow_label = be32_to_cpu(mcast->mcmember.flow_label),
.hop_limit = mcast->mcmember.hop_limit,
@ -258,17 +258,8 @@ static int ipoib_mcast_join_finish(struct ipoib_mcast *mcast,
.traffic_class = mcast->mcmember.traffic_class
}
};
int path_rate = ib_sa_rate_enum_to_int(mcast->mcmember.rate);
av.grh.dgid = mcast->mcmember.mgid;
if (path_rate > 0 && priv->local_rate > path_rate)
av.static_rate = (priv->local_rate - 1) / path_rate;
ipoib_dbg_mcast(priv, "static_rate %d for local port %dX, mcmember %dX\n",
av.static_rate, priv->local_rate,
ib_sa_rate_enum_to_int(mcast->mcmember.rate));
ah = ipoib_create_ah(dev, priv->pd, &av);
if (!ah) {
ipoib_warn(priv, "ib_address_create failed\n");
@ -618,6 +609,22 @@ int ipoib_mcast_start_thread(struct net_device *dev)
return 0;
}
static void wait_for_mcast_join(struct ipoib_dev_priv *priv,
struct ipoib_mcast *mcast)
{
spin_lock_irq(&priv->lock);
if (mcast && mcast->query) {
ib_sa_cancel_query(mcast->query_id, mcast->query);
mcast->query = NULL;
spin_unlock_irq(&priv->lock);
ipoib_dbg_mcast(priv, "waiting for MGID " IPOIB_GID_FMT "\n",
IPOIB_GID_ARG(mcast->mcmember.mgid));
wait_for_completion(&mcast->done);
}
else
spin_unlock_irq(&priv->lock);
}
int ipoib_mcast_stop_thread(struct net_device *dev, int flush)
{
struct ipoib_dev_priv *priv = netdev_priv(dev);
@ -637,28 +644,10 @@ int ipoib_mcast_stop_thread(struct net_device *dev, int flush)
if (flush)
flush_workqueue(ipoib_workqueue);
spin_lock_irq(&priv->lock);
if (priv->broadcast && priv->broadcast->query) {
ib_sa_cancel_query(priv->broadcast->query_id, priv->broadcast->query);
priv->broadcast->query = NULL;
spin_unlock_irq(&priv->lock);
ipoib_dbg_mcast(priv, "waiting for bcast\n");
wait_for_completion(&priv->broadcast->done);
} else
spin_unlock_irq(&priv->lock);
wait_for_mcast_join(priv, priv->broadcast);
list_for_each_entry(mcast, &priv->multicast_list, list) {
spin_lock_irq(&priv->lock);
if (mcast->query) {
ib_sa_cancel_query(mcast->query_id, mcast->query);
mcast->query = NULL;
spin_unlock_irq(&priv->lock);
ipoib_dbg_mcast(priv, "waiting for MGID " IPOIB_GID_FMT "\n",
IPOIB_GID_ARG(mcast->mcmember.mgid));
wait_for_completion(&mcast->done);
} else
spin_unlock_irq(&priv->lock);
}
list_for_each_entry(mcast, &priv->multicast_list, list)
wait_for_mcast_join(priv, mcast);
return 0;
}
@ -772,13 +761,11 @@ out:
if (skb->dst &&
skb->dst->neighbour &&
!*to_ipoib_neigh(skb->dst->neighbour)) {
struct ipoib_neigh *neigh = kmalloc(sizeof *neigh, GFP_ATOMIC);
struct ipoib_neigh *neigh = ipoib_neigh_alloc(skb->dst->neighbour);
if (neigh) {
kref_get(&mcast->ah->ref);
neigh->ah = mcast->ah;
neigh->neighbour = skb->dst->neighbour;
*to_ipoib_neigh(skb->dst->neighbour) = neigh;
list_add_tail(&neigh->list, &mcast->neigh_list);
}
}
@ -913,6 +900,7 @@ void ipoib_mcast_restart_task(void *dev_ptr)
/* We have to cancel outside of the spinlock */
list_for_each_entry_safe(mcast, tmcast, &remove_list, list) {
wait_for_mcast_join(priv, mcast);
ipoib_mcast_leave(mcast->dev, mcast);
ipoib_mcast_free(mcast);
}

View File

@ -159,8 +159,8 @@ int ipoib_transport_dev_init(struct net_device *dev, struct ib_device *ca)
struct ipoib_dev_priv *priv = netdev_priv(dev);
struct ib_qp_init_attr init_attr = {
.cap = {
.max_send_wr = IPOIB_TX_RING_SIZE,
.max_recv_wr = IPOIB_RX_RING_SIZE,
.max_send_wr = ipoib_sendq_size,
.max_recv_wr = ipoib_recvq_size,
.max_send_sge = 1,
.max_recv_sge = 1
},
@ -175,7 +175,7 @@ int ipoib_transport_dev_init(struct net_device *dev, struct ib_device *ca)
}
priv->cq = ib_create_cq(priv->ca, ipoib_ib_completion, NULL, dev,
IPOIB_TX_RING_SIZE + IPOIB_RX_RING_SIZE + 1);
ipoib_sendq_size + ipoib_recvq_size + 1);
if (IS_ERR(priv->cq)) {
printk(KERN_WARNING "%s: failed to create CQ\n", ca->name);
goto out_free_pd;

View File

@ -1434,6 +1434,7 @@ static int srp_parse_options(const char *buf, struct srp_target_port *target)
p = match_strdup(args);
if (strlen(p) != 32) {
printk(KERN_WARNING PFX "bad dest GID parameter '%s'\n", p);
kfree(p);
goto out;
}

View File

@ -109,7 +109,7 @@ isdn_ppp_free(isdn_net_local * lp)
{
struct ippp_struct *is;
if (lp->ppp_slot < 0 || lp->ppp_slot > ISDN_MAX_CHANNELS) {
if (lp->ppp_slot < 0 || lp->ppp_slot >= ISDN_MAX_CHANNELS) {
printk(KERN_ERR "%s: ppp_slot(%d) out of range\n",
__FUNCTION__, lp->ppp_slot);
return 0;
@ -126,7 +126,7 @@ isdn_ppp_free(isdn_net_local * lp)
lp->netdev->pb->ref_ct--;
spin_unlock(&lp->netdev->pb->lock);
#endif /* CONFIG_ISDN_MPP */
if (lp->ppp_slot < 0 || lp->ppp_slot > ISDN_MAX_CHANNELS) {
if (lp->ppp_slot < 0 || lp->ppp_slot >= ISDN_MAX_CHANNELS) {
printk(KERN_ERR "%s: ppp_slot(%d) now invalid\n",
__FUNCTION__, lp->ppp_slot);
return 0;
@ -279,7 +279,7 @@ isdn_ppp_open(int min, struct file *file)
int slot;
struct ippp_struct *is;
if (min < 0 || min > ISDN_MAX_CHANNELS)
if (min < 0 || min >= ISDN_MAX_CHANNELS)
return -ENODEV;
slot = isdn_ppp_get_slot();
@ -1042,7 +1042,7 @@ isdn_ppp_push_higher(isdn_net_dev * net_dev, isdn_net_local * lp, struct sk_buff
if (lp->master) { // FIXME?
mlp = (isdn_net_local *) lp->master->priv;
slot = mlp->ppp_slot;
if (slot < 0 || slot > ISDN_MAX_CHANNELS) {
if (slot < 0 || slot >= ISDN_MAX_CHANNELS) {
printk(KERN_ERR "isdn_ppp_push_higher: master->ppp_slot(%d)\n",
lp->ppp_slot);
goto drop_packet;
@ -1264,7 +1264,7 @@ isdn_ppp_xmit(struct sk_buff *skb, struct net_device *netdev)
/* we have our lp locked from now on */
slot = lp->ppp_slot;
if (slot < 0 || slot > ISDN_MAX_CHANNELS) {
if (slot < 0 || slot >= ISDN_MAX_CHANNELS) {
printk(KERN_ERR "isdn_ppp_xmit: lp->ppp_slot(%d)\n",
lp->ppp_slot);
kfree_skb(skb);
@ -1603,7 +1603,7 @@ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp,
mp = net_dev->pb;
stats = &mp->stats;
slot = lp->ppp_slot;
if (slot < 0 || slot > ISDN_MAX_CHANNELS) {
if (slot < 0 || slot >= ISDN_MAX_CHANNELS) {
printk(KERN_ERR "%s: lp->ppp_slot(%d)\n",
__FUNCTION__, lp->ppp_slot);
stats->frame_drops++;
@ -1640,7 +1640,7 @@ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp,
is->last_link_seqno = minseq = newseq;
for (lpq = net_dev->queue;;) {
slot = lpq->ppp_slot;
if (slot < 0 || slot > ISDN_MAX_CHANNELS) {
if (slot < 0 || slot >= ISDN_MAX_CHANNELS) {
printk(KERN_ERR "%s: lpq->ppp_slot(%d)\n",
__FUNCTION__, lpq->ppp_slot);
} else {
@ -2648,7 +2648,7 @@ static void isdn_ppp_receive_ccp(isdn_net_dev *net_dev, isdn_net_local *lp,
printk(KERN_DEBUG "Received CCP frame from peer slot(%d)\n",
lp->ppp_slot);
if (lp->ppp_slot < 0 || lp->ppp_slot > ISDN_MAX_CHANNELS) {
if (lp->ppp_slot < 0 || lp->ppp_slot >= ISDN_MAX_CHANNELS) {
printk(KERN_ERR "%s: lp->ppp_slot(%d) out of range\n",
__FUNCTION__, lp->ppp_slot);
return;
@ -2658,7 +2658,7 @@ static void isdn_ppp_receive_ccp(isdn_net_dev *net_dev, isdn_net_local *lp,
if(lp->master) {
int slot = ((isdn_net_local *) (lp->master->priv))->ppp_slot;
if (slot < 0 || slot > ISDN_MAX_CHANNELS) {
if (slot < 0 || slot >= ISDN_MAX_CHANNELS) {
printk(KERN_ERR "%s: slot(%d) out of range\n",
__FUNCTION__, slot);
return;
@ -2845,7 +2845,7 @@ static void isdn_ppp_send_ccp(isdn_net_dev *net_dev, isdn_net_local *lp, struct
if (lp->master) {
slot = ((isdn_net_local *) (lp->master->priv))->ppp_slot;
if (slot < 0 || slot > ISDN_MAX_CHANNELS) {
if (slot < 0 || slot >= ISDN_MAX_CHANNELS) {
printk(KERN_ERR "%s: slot(%d) out of range\n",
__FUNCTION__, slot);
return;

View File

@ -163,6 +163,7 @@ void md_new_event(mddev_t *mddev)
{
atomic_inc(&md_event_count);
wake_up(&md_event_waiters);
sysfs_notify(&mddev->kobj, NULL, "sync_action");
}
EXPORT_SYMBOL_GPL(md_new_event);

View File

@ -366,7 +366,15 @@ mptsas_sas_enclosure_pg0(MPT_ADAPTER *ioc, struct mptsas_enclosure *enclosure,
static int
mptsas_slave_configure(struct scsi_device *sdev)
{
sas_read_port_mode_page(sdev);
struct Scsi_Host *host = sdev->host;
MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
/*
* RAID volumes placed beyond the last expected port.
* Ignore sending sas mode pages in that case..
*/
if (sdev->channel < hd->ioc->num_ports)
sas_read_port_mode_page(sdev);
return mptscsih_slave_configure(sdev);
}

View File

@ -2,6 +2,7 @@
*
* Copyright (C) 2002 David S. Miller (davem@redhat.com)
* Fixed by Pekka Pietikainen (pp@ee.oulu.fi)
* Copyright (C) 2006 Broadcom Corporation.
*
* Distribute under GPL.
*/
@ -28,8 +29,8 @@
#define DRV_MODULE_NAME "b44"
#define PFX DRV_MODULE_NAME ": "
#define DRV_MODULE_VERSION "0.97"
#define DRV_MODULE_RELDATE "Nov 30, 2005"
#define DRV_MODULE_VERSION "1.00"
#define DRV_MODULE_RELDATE "Apr 7, 2006"
#define B44_DEF_MSG_ENABLE \
(NETIF_MSG_DRV | \
@ -136,7 +137,7 @@ static inline unsigned long br32(const struct b44 *bp, unsigned long reg)
return readl(bp->regs + reg);
}
static inline void bw32(const struct b44 *bp,
static inline void bw32(const struct b44 *bp,
unsigned long reg, unsigned long val)
{
writel(val, bp->regs + reg);
@ -286,13 +287,13 @@ static void __b44_cam_write(struct b44 *bp, unsigned char *data, int index)
val |= ((u32) data[4]) << 8;
val |= ((u32) data[5]) << 0;
bw32(bp, B44_CAM_DATA_LO, val);
val = (CAM_DATA_HI_VALID |
val = (CAM_DATA_HI_VALID |
(((u32) data[0]) << 8) |
(((u32) data[1]) << 0));
bw32(bp, B44_CAM_DATA_HI, val);
bw32(bp, B44_CAM_CTRL, (CAM_CTRL_WRITE |
(index << CAM_CTRL_INDEX_SHIFT)));
b44_wait_bit(bp, B44_CAM_CTRL, CAM_CTRL_BUSY, 100, 1);
b44_wait_bit(bp, B44_CAM_CTRL, CAM_CTRL_BUSY, 100, 1);
}
static inline void __b44_disable_ints(struct b44 *bp)
@ -410,25 +411,18 @@ static void __b44_set_flow_ctrl(struct b44 *bp, u32 pause_flags)
static void b44_set_flow_ctrl(struct b44 *bp, u32 local, u32 remote)
{
u32 pause_enab = bp->flags & (B44_FLAG_TX_PAUSE |
B44_FLAG_RX_PAUSE);
u32 pause_enab = 0;
if (local & ADVERTISE_PAUSE_CAP) {
if (local & ADVERTISE_PAUSE_ASYM) {
if (remote & LPA_PAUSE_CAP)
pause_enab |= (B44_FLAG_TX_PAUSE |
B44_FLAG_RX_PAUSE);
else if (remote & LPA_PAUSE_ASYM)
pause_enab |= B44_FLAG_RX_PAUSE;
} else {
if (remote & LPA_PAUSE_CAP)
pause_enab |= (B44_FLAG_TX_PAUSE |
B44_FLAG_RX_PAUSE);
}
} else if (local & ADVERTISE_PAUSE_ASYM) {
if ((remote & LPA_PAUSE_CAP) &&
(remote & LPA_PAUSE_ASYM))
pause_enab |= B44_FLAG_TX_PAUSE;
/* The driver supports only rx pause by default because
the b44 mac tx pause mechanism generates excessive
pause frames.
Use ethtool to turn on b44 tx pause if necessary.
*/
if ((local & ADVERTISE_PAUSE_CAP) &&
(local & ADVERTISE_PAUSE_ASYM)){
if ((remote & LPA_PAUSE_ASYM) &&
!(remote & LPA_PAUSE_CAP))
pause_enab |= B44_FLAG_RX_PAUSE;
}
__b44_set_flow_ctrl(bp, pause_enab);
@ -1063,7 +1057,7 @@ static int b44_change_mtu(struct net_device *dev, int new_mtu)
spin_unlock_irq(&bp->lock);
b44_enable_ints(bp);
return 0;
}
@ -1381,7 +1375,7 @@ static void b44_init_hw(struct b44 *bp)
bw32(bp, B44_DMARX_ADDR, bp->rx_ring_dma + bp->dma_offset);
bw32(bp, B44_DMARX_PTR, bp->rx_pending);
bp->rx_prod = bp->rx_pending;
bp->rx_prod = bp->rx_pending;
bw32(bp, B44_MIB_CTRL, MIB_CTRL_CLR_ON_READ);
@ -1553,9 +1547,9 @@ static void __b44_set_rx_mode(struct net_device *dev)
val |= RXCONFIG_ALLMULTI;
else
i = __b44_load_mcast(bp, dev);
for (; i < 64; i++) {
__b44_cam_write(bp, zero, i);
__b44_cam_write(bp, zero, i);
}
bw32(bp, B44_RXCONFIG, val);
val = br32(bp, B44_CAM_CTRL);
@ -1737,7 +1731,7 @@ static int b44_set_ringparam(struct net_device *dev,
spin_unlock_irq(&bp->lock);
b44_enable_ints(bp);
return 0;
}
@ -1782,7 +1776,7 @@ static int b44_set_pauseparam(struct net_device *dev,
spin_unlock_irq(&bp->lock);
b44_enable_ints(bp);
return 0;
}
@ -1898,7 +1892,7 @@ static int __devinit b44_get_invariants(struct b44 *bp)
bp->core_unit = ssb_core_unit(bp);
bp->dma_offset = SB_PCI_DMA;
/* XXX - really required?
/* XXX - really required?
bp->flags |= B44_FLAG_BUGGY_TXPTR;
*/
out:
@ -1946,7 +1940,7 @@ static int __devinit b44_init_one(struct pci_dev *pdev,
"aborting.\n");
goto err_out_free_res;
}
err = pci_set_consistent_dma_mask(pdev, (u64) B44_DMA_MASK);
if (err) {
printk(KERN_ERR PFX "No usable DMA configuration, "
@ -2041,9 +2035,9 @@ static int __devinit b44_init_one(struct pci_dev *pdev,
pci_save_state(bp->pdev);
/* Chip reset provides power to the b44 MAC & PCI cores, which
/* Chip reset provides power to the b44 MAC & PCI cores, which
* is necessary for MAC register access.
*/
*/
b44_chip_reset(bp);
printk(KERN_INFO "%s: Broadcom 4400 10/100BaseT Ethernet ", dev->name);
@ -2091,10 +2085,10 @@ static int b44_suspend(struct pci_dev *pdev, pm_message_t state)
del_timer_sync(&bp->timer);
spin_lock_irq(&bp->lock);
spin_lock_irq(&bp->lock);
b44_halt(bp);
netif_carrier_off(bp->dev);
netif_carrier_off(bp->dev);
netif_device_detach(bp->dev);
b44_free_rings(bp);

View File

@ -63,7 +63,7 @@
/* Time in jiffies before concluding the transmitter is hung. */
#define TX_TIMEOUT (5*HZ)
static char version[] __devinitdata =
static const char version[] __devinitdata =
"Broadcom NetXtreme II Gigabit Ethernet Driver " DRV_MODULE_NAME " v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
MODULE_AUTHOR("Michael Chan <mchan@broadcom.com>");

View File

@ -1,177 +0,0 @@
/* $Linux: hydra.h,v 1.0 1994/10/26 02:03:47 cgd Exp $ */
/*
* Copyright (c) 1994 Timo Rossi
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Timo Rossi
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* The Hydra Systems card uses the National Semiconductor
* 8390 NIC (Network Interface Controller) chip, located
* at card base address + 0xffe1. NIC registers are accessible
* only at odd byte addresses, so the register offsets must
* be multiplied by two.
*
* Card address PROM is located at card base + 0xffc0 (even byte addresses)
*
* RAM starts at the card base address, and is 16K or 64K.
* The current Amiga NetBSD hydra driver is hardwired for 16K.
* It seems that the RAM should be accessed as words or longwords only.
*
*/
/* adapted for Linux by Topi Kanerva 03/29/95
with original author's permission */
#define HYDRA_NIC_BASE 0xffe1
/* Page0 registers */
#define NIC_CR 0 /* Command register */
#define NIC_PSTART (1*2) /* Page start (write) */
#define NIC_PSTOP (2*2) /* Page stop (write) */
#define NIC_BNDRY (3*2) /* Boundary pointer */
#define NIC_TSR (4*2) /* Transmit status (read) */
#define NIC_TPSR (4*2) /* Transmit page start (write) */
#define NIC_NCR (5*2) /* Number of collisions, read */
#define NIC_TBCR0 (5*2) /* Transmit byte count low (write) */
#define NIC_FIFO (6*2) /* FIFO reg. (read) */
#define NIC_TBCR1 (6*2) /* Transmit byte count high (write) */
#define NIC_ISR (7*2) /* Interrupt status register */
#define NIC_RBCR0 (0xa*2) /* Remote byte count low (write) */
#define NIC_RBCR1 (0xb*2) /* Remote byte count high (write) */
#define NIC_RSR (0xc*2) /* Receive status (read) */
#define NIC_RCR (0xc*2) /* Receive config (write) */
#define NIC_CNTR0 (0xd*2) /* Frame alignment error count (read) */
#define NIC_TCR (0xd*2) /* Transmit config (write) */
#define NIC_CNTR1 (0xe*2) /* CRC error counter (read) */
#define NIC_DCR (0xe*2) /* Data config (write) */
#define NIC_CNTR2 (0xf*2) /* missed packet counter (read) */
#define NIC_IMR (0xf*2) /* Interrupt mask reg. (write) */
/* Page1 registers */
#define NIC_PAR0 (1*2) /* Physical address */
#define NIC_PAR1 (2*2)
#define NIC_PAR2 (3*2)
#define NIC_PAR3 (4*2)
#define NIC_PAR4 (5*2)
#define NIC_PAR5 (6*2)
#define NIC_CURR (7*2) /* Current RX ring-buffer page */
#define NIC_MAR0 (8*2) /* Multicast address */
#define NIC_MAR1 (9*2)
#define NIC_MAR2 (0xa*2)
#define NIC_MAR3 (0xb*2)
#define NIC_MAR4 (0xc*2)
#define NIC_MAR5 (0xd*2)
#define NIC_MAR6 (0xe*2)
#define NIC_MAR7 (0xf*2)
/* Command register definitions */
#define CR_STOP 0x01 /* Stop -- software reset command */
#define CR_START 0x02 /* Start */
#define CR_TXP 0x04 /* Transmit packet */
#define CR_RD0 0x08 /* Remote DMA cmd */
#define CR_RD1 0x10
#define CR_RD2 0x20
#define CR_NODMA CR_RD2
#define CR_PS0 0x40 /* Page select */
#define CR_PS1 0x80
#define CR_PAGE0 0
#define CR_PAGE1 CR_PS0
#define CR_PAGE2 CR_PS1
/* Interrupt status reg. definitions */
#define ISR_PRX 0x01 /* Packet received without errors */
#define ISR_PTX 0x02 /* Packet transmitted without errors */
#define ISR_RXE 0x04 /* Receive error */
#define ISR_TXE 0x08 /* Transmit error */
#define ISR_OVW 0x10 /* Ring buffer overrun */
#define ISR_CNT 0x20 /* Counter overflow */
#define ISR_RDC 0x40 /* Remote DMA compile */
#define ISR_RST 0x80 /* Reset status */
/* Data config reg. definitions */
#define DCR_WTS 0x01 /* Word transfer select */
#define DCR_BOS 0x02 /* Byte order select */
#define DCR_LAS 0x04 /* Long address select */
#define DCR_LS 0x08 /* Loopback select */
#define DCR_AR 0x10 /* Auto-init remote */
#define DCR_FT0 0x20 /* FIFO threshold select */
#define DCR_FT1 0x40
/* Transmit config reg. definitions */
#define TCR_CRC 0x01 /* Inhibit CRC */
#define TCR_LB0 0x02 /* Loopback control */
#define TCR_LB1 0x04
#define TCR_ATD 0x08 /* Auto transmit disable */
#define TCR_OFST 0x10 /* Collision offset enable */
/* Transmit status reg. definitions */
#define TSR_PTX 0x01 /* Packet transmitted */
#define TSR_COL 0x04 /* Transmit collided */
#define TSR_ABT 0x08 /* Transmit aborted */
#define TSR_CRS 0x10 /* Carrier sense lost */
#define TSR_FU 0x20 /* FIFO underrun */
#define TSR_CDH 0x40 /* CD Heartbeat */
#define TSR_OWC 0x80 /* Out of Window Collision */
/* Receiver config register definitions */
#define RCR_SEP 0x01 /* Save errored packets */
#define RCR_AR 0x02 /* Accept runt packets */
#define RCR_AB 0x04 /* Accept broadcast */
#define RCR_AM 0x08 /* Accept multicast */
#define RCR_PRO 0x10 /* Promiscuous mode */
#define RCR_MON 0x20 /* Monitor mode */
/* Receiver status register definitions */
#define RSR_PRX 0x01 /* Packet received without error */
#define RSR_CRC 0x02 /* CRC error */
#define RSR_FAE 0x04 /* Frame alignment error */
#define RSR_FO 0x08 /* FIFO overrun */
#define RSR_MPA 0x10 /* Missed packet */
#define RSR_PHY 0x20 /* Physical address */
#define RSR_DIS 0x40 /* Received disabled */
#define RSR_DFR 0x80 /* Deferring (jabber) */
/* Hydra System card address PROM offset */
#define HYDRA_ADDRPROM 0xffc0

View File

@ -1815,14 +1815,14 @@ static int irda_usb_probe(struct usb_interface *intf,
self->needspatch = (ret < 0);
if (ret < 0) {
printk("patch_device failed\n");
goto err_out_4;
goto err_out_5;
}
/* replace IrDA class descriptor with what patched device is now reporting */
irda_desc = irda_usb_find_class_desc (self->usbintf);
if (irda_desc == NULL) {
ret = -ENODEV;
goto err_out_4;
goto err_out_5;
}
if (self->irda_desc)
kfree (self->irda_desc);
@ -1832,6 +1832,8 @@ static int irda_usb_probe(struct usb_interface *intf,
return 0;
err_out_5:
unregister_netdev(self->netdev);
err_out_4:
kfree(self->speed_buff);
err_out_3:

View File

@ -225,6 +225,8 @@ static int __init smsc_superio_lpc(unsigned short cfg_base);
#ifdef CONFIG_PCI
static int __init preconfigure_smsc_chip(struct smsc_ircc_subsystem_configuration *conf);
static int __init preconfigure_through_82801(struct pci_dev *dev, struct smsc_ircc_subsystem_configuration *conf);
static void __init preconfigure_ali_port(struct pci_dev *dev,
unsigned short port);
static int __init preconfigure_through_ali(struct pci_dev *dev, struct smsc_ircc_subsystem_configuration *conf);
static int __init smsc_ircc_preconfigure_subsystems(unsigned short ircc_cfg,
unsigned short ircc_fir,
@ -2327,9 +2329,14 @@ static int __init smsc_superio_lpc(unsigned short cfg_base)
* pre-configuration not properly done by the BIOS (especially laptops)
* This code is based in part on smcinit.c, tosh1800-smcinit.c
* and tosh2450-smcinit.c. The table lists the device entries
* for ISA bridges with an LPC (Local Peripheral Configurator)
* that are in turn used to configure the SMSC device with default
* SIR and FIR I/O ports, DMA and IRQ.
* for ISA bridges with an LPC (Low Pin Count) controller which
* handles the communication with the SMSC device. After the LPC
* controller is initialized through PCI, the SMSC device is initialized
* through a dedicated port in the ISA port-mapped I/O area, this latter
* area is used to configure the SMSC device with default
* SIR and FIR I/O ports, DMA and IRQ. Different vendors have
* used different sets of parameters and different control port
* addresses making a subsystem device table necessary.
*/
#ifdef CONFIG_PCI
#define PCIID_VENDOR_INTEL 0x8086
@ -2340,9 +2347,10 @@ static struct smsc_ircc_subsystem_configuration subsystem_configurations[] __dev
.device = 0x24cc,
.subvendor = 0x103c,
.subdevice = 0x088c,
.sir_io = 0x02f8, /* Quite certain these are the same for nc8000 as for nc6000 */
/* Quite certain these are the same for nc8000 as for nc6000 */
.sir_io = 0x02f8,
.fir_io = 0x0130,
.fir_irq = 0x09,
.fir_irq = 0x05,
.fir_dma = 0x03,
.cfg_base = 0x004e,
.preconfigure = preconfigure_through_82801,
@ -2355,60 +2363,79 @@ static struct smsc_ircc_subsystem_configuration subsystem_configurations[] __dev
.subdevice = 0x0890,
.sir_io = 0x02f8,
.fir_io = 0x0130,
.fir_irq = 0x09,
.fir_irq = 0x05,
.fir_dma = 0x03,
.cfg_base = 0x004e,
.preconfigure = preconfigure_through_82801,
.name = "HP nc6000",
},
{
.vendor = PCIID_VENDOR_INTEL, /* Intel 82801DB/DBL (ICH4/ICH4-L) LPC Interface Bridge */
/* Intel 82801DB/DBL (ICH4/ICH4-L) LPC Interface Bridge */
.vendor = PCIID_VENDOR_INTEL,
.device = 0x24c0,
.subvendor = 0x1179,
.subdevice = 0xffff, /* 0xffff is "any", Not sure, 0x0001 or 0x0002 */
.subdevice = 0xffff, /* 0xffff is "any" */
.sir_io = 0x03f8,
.fir_io = 0x0130,
.fir_irq = 0x07,
.fir_dma = 0x01,
.cfg_base = 0x002e,
.preconfigure = preconfigure_through_82801,
.name = "Toshiba Satellite 2450",
.name = "Toshiba laptop with Intel 82801DB/DBL LPC bridge",
},
{
.vendor = PCIID_VENDOR_INTEL, /* Intel 82801CAM ISA bridge */
.device = 0x248c, /* Some use 24cc? */
.device = 0x248c,
.subvendor = 0x1179,
.subdevice = 0xffff, /* 0xffff is "any", Not sure, 0x0001 or 0x0002 */
.subdevice = 0xffff, /* 0xffff is "any" */
.sir_io = 0x03f8,
.fir_io = 0x0130,
.fir_irq = 0x03,
.fir_dma = 0x03,
.cfg_base = 0x002e,
.preconfigure = preconfigure_through_82801,
.name = "Toshiba Satellite 5100/5200, Tecra 9100",
.name = "Toshiba laptop with Intel 82801CAM ISA bridge",
},
{
.vendor = PCIID_VENDOR_ALI, /* ALi M1533/M1535 PCI to ISA Bridge [Aladdin IV/V/V+] */
/* 82801DBM (ICH4-M) LPC Interface Bridge */
.vendor = PCIID_VENDOR_INTEL,
.device = 0x24cc,
.subvendor = 0x1179,
.subdevice = 0xffff, /* 0xffff is "any" */
.sir_io = 0x03f8,
.fir_io = 0x0130,
.fir_irq = 0x03,
.fir_dma = 0x03,
.cfg_base = 0x002e,
.preconfigure = preconfigure_through_82801,
.name = "Toshiba laptop with Intel 8281DBM LPC bridge",
},
{
/* ALi M1533/M1535 PCI to ISA Bridge [Aladdin IV/V/V+] */
.vendor = PCIID_VENDOR_ALI,
.device = 0x1533,
.subvendor = 0x1179,
.subdevice = 0xffff, /* 0xffff is "any", Not sure, 0x0001 or 0x0002 */
.subdevice = 0xffff, /* 0xffff is "any" */
.sir_io = 0x02e8,
.fir_io = 0x02f8,
.fir_irq = 0x07,
.fir_dma = 0x03,
.cfg_base = 0x002e,
.preconfigure = preconfigure_through_ali,
.name = "Toshiba Satellite 1800",
.name = "Toshiba laptop with ALi ISA bridge",
},
{ } // Terminator
};
/*
* This sets up the basic SMSC parameters (FIR port, SIR port, FIR DMA, FIR IRQ)
* This sets up the basic SMSC parameters
* (FIR port, SIR port, FIR DMA, FIR IRQ)
* through the chip configuration port.
*/
static int __init preconfigure_smsc_chip(struct smsc_ircc_subsystem_configuration *conf)
static int __init preconfigure_smsc_chip(struct
smsc_ircc_subsystem_configuration
*conf)
{
unsigned short iobase = conf->cfg_base;
unsigned char tmpbyte;
@ -2416,7 +2443,9 @@ static int __init preconfigure_smsc_chip(struct smsc_ircc_subsystem_configuratio
outb(LPC47N227_CFGACCESSKEY, iobase); // enter configuration state
outb(SMSCSIOFLAT_DEVICEID_REG, iobase); // set for device ID
tmpbyte = inb(iobase +1); // Read device ID
IRDA_DEBUG(0, "Detected Chip id: 0x%02x, setting up registers...\n",tmpbyte);
IRDA_DEBUG(0,
"Detected Chip id: 0x%02x, setting up registers...\n",
tmpbyte);
/* Disable UART1 and set up SIR I/O port */
outb(0x24, iobase); // select CR24 - UART1 base addr
@ -2426,6 +2455,7 @@ static int __init preconfigure_smsc_chip(struct smsc_ircc_subsystem_configuratio
tmpbyte = inb(iobase + 1);
if (tmpbyte != (conf->sir_io >> 2) ) {
IRDA_WARNING("ERROR: could not configure SIR ioport.\n");
IRDA_WARNING("Try to supply ircc_cfg argument.\n");
return -ENXIO;
}
@ -2461,7 +2491,8 @@ static int __init preconfigure_smsc_chip(struct smsc_ircc_subsystem_configuratio
outb(SMSCSIOFLAT_UARTMODE0C_REG, iobase); // CR0C - UART mode
tmpbyte = inb(iobase + 1);
tmpbyte &= ~SMSCSIOFLAT_UART2MODE_MASK | SMSCSIOFLAT_UART2MODE_VAL_IRDA;
tmpbyte &= ~SMSCSIOFLAT_UART2MODE_MASK |
SMSCSIOFLAT_UART2MODE_VAL_IRDA;
outb(tmpbyte, iobase + 1); // enable IrDA (HPSIR) mode, high speed
outb(LPC47N227_APMBOOTDRIVE_REG, iobase); // CR07 - Auto Pwr Mgt/boot drive sel
@ -2486,53 +2517,226 @@ static int __init preconfigure_smsc_chip(struct smsc_ircc_subsystem_configuratio
return 0;
}
/* 82801CAM registers */
/* 82801CAM generic registers */
#define VID 0x00
#define DID 0x02
#define PIRQA_ROUT 0x60
#define PIRQ_A_D_ROUT 0x60
#define SIRQ_CNTL 0x64
#define PIRQ_E_H_ROUT 0x68
#define PCI_DMA_C 0x90
/* LPC-specific registers */
#define COM_DEC 0xe0
#define GEN1_DEC 0xe4
#define LPC_EN 0xe6
#define GEN2_DEC 0xec
/*
* Sets up the I/O range using the 82801CAM ISA bridge, 82801DBM LPC bridge or
* Intel 82801DB/DBL (ICH4/ICH4-L) LPC Interface Bridge. They all work the same way!
* Sets up the I/O range using the 82801CAM ISA bridge, 82801DBM LPC bridge
* or Intel 82801DB/DBL (ICH4/ICH4-L) LPC Interface Bridge.
* They all work the same way!
*/
static int __init preconfigure_through_82801(struct pci_dev *dev,
struct smsc_ircc_subsystem_configuration *conf)
struct
smsc_ircc_subsystem_configuration
*conf)
{
unsigned short tmpword;
int ret;
unsigned char tmpbyte;
IRDA_MESSAGE("Setting up the SMSC device via the 82801 controller.\n");
pci_write_config_byte(dev, COM_DEC, 0x10);
IRDA_MESSAGE("Setting up Intel 82801 controller and SMSC device\n");
/*
* Select the range for the COMA COM port (SIR)
* Register COM_DEC:
* Bit 7: reserved
* Bit 6-4, COMB decode range
* Bit 3: reserved
* Bit 2-0, COMA decode range
*
* Decode ranges:
* 000 = 0x3f8-0x3ff (COM1)
* 001 = 0x2f8-0x2ff (COM2)
* 010 = 0x220-0x227
* 011 = 0x228-0x22f
* 100 = 0x238-0x23f
* 101 = 0x2e8-0x2ef (COM4)
* 110 = 0x338-0x33f
* 111 = 0x3e8-0x3ef (COM3)
*/
pci_read_config_byte(dev, COM_DEC, &tmpbyte);
tmpbyte &= 0xf8; /* mask COMA bits */
switch(conf->sir_io) {
case 0x3f8:
tmpbyte |= 0x00;
break;
case 0x2f8:
tmpbyte |= 0x01;
break;
case 0x220:
tmpbyte |= 0x02;
break;
case 0x228:
tmpbyte |= 0x03;
break;
case 0x238:
tmpbyte |= 0x04;
break;
case 0x2e8:
tmpbyte |= 0x05;
break;
case 0x338:
tmpbyte |= 0x06;
break;
case 0x3e8:
tmpbyte |= 0x07;
break;
default:
tmpbyte |= 0x01; /* COM2 default */
}
IRDA_DEBUG(1, "COM_DEC (write): 0x%02x\n", tmpbyte);
pci_write_config_byte(dev, COM_DEC, tmpbyte);
/* Enable LPC */
pci_read_config_word(dev, LPC_EN, &tmpword); /* LPC_EN register */
tmpword &= 0xfffd; /* mask bit 1 */
tmpword |= 0x0001; /* set bit 0 : COMA addr range enable */
/* Enable Low Pin Count interface */
pci_read_config_word(dev, LPC_EN, &tmpword);
/* These seem to be set up at all times,
* just make sure it is properly set.
*/
switch(conf->cfg_base) {
case 0x04e:
tmpword |= 0x2000;
break;
case 0x02e:
tmpword |= 0x1000;
break;
case 0x062:
tmpword |= 0x0800;
break;
case 0x060:
tmpword |= 0x0400;
break;
default:
IRDA_WARNING("Uncommon I/O base address: 0x%04x\n",
conf->cfg_base);
break;
}
tmpword &= 0xfffd; /* disable LPC COMB */
tmpword |= 0x0001; /* set bit 0 : enable LPC COMA addr range (GEN2) */
IRDA_DEBUG(1, "LPC_EN (write): 0x%04x\n", tmpword);
pci_write_config_word(dev, LPC_EN, tmpword);
/* Setup DMA */
pci_write_config_word(dev, PCI_DMA_C, 0xc0c0); /* LPC I/F DMA on, channel 3 -- rtm (?? PCI DMA ?) */
pci_write_config_word(dev, GEN2_DEC, 0x131); /* LPC I/F 2nd decode range */
/*
* Configure LPC DMA channel
* PCI_DMA_C bits:
* Bit 15-14: DMA channel 7 select
* Bit 13-12: DMA channel 6 select
* Bit 11-10: DMA channel 5 select
* Bit 9-8: Reserved
* Bit 7-6: DMA channel 3 select
* Bit 5-4: DMA channel 2 select
* Bit 3-2: DMA channel 1 select
* Bit 1-0: DMA channel 0 select
* 00 = Reserved value
* 01 = PC/PCI DMA
* 10 = Reserved value
* 11 = LPC I/F DMA
*/
pci_read_config_word(dev, PCI_DMA_C, &tmpword);
switch(conf->fir_dma) {
case 0x07:
tmpword |= 0xc000;
break;
case 0x06:
tmpword |= 0x3000;
break;
case 0x05:
tmpword |= 0x0c00;
break;
case 0x03:
tmpword |= 0x00c0;
break;
case 0x02:
tmpword |= 0x0030;
break;
case 0x01:
tmpword |= 0x000c;
break;
case 0x00:
tmpword |= 0x0003;
break;
default:
break; /* do not change settings */
}
IRDA_DEBUG(1, "PCI_DMA_C (write): 0x%04x\n", tmpword);
pci_write_config_word(dev, PCI_DMA_C, tmpword);
/*
* GEN2_DEC bits:
* Bit 15-4: Generic I/O range
* Bit 3-1: reserved (read as 0)
* Bit 0: enable GEN2 range on LPC I/F
*/
tmpword = conf->fir_io & 0xfff8;
tmpword |= 0x0001;
IRDA_DEBUG(1, "GEN2_DEC (write): 0x%04x\n", tmpword);
pci_write_config_word(dev, GEN2_DEC, tmpword);
/* Pre-configure chip */
ret = preconfigure_smsc_chip(conf);
return preconfigure_smsc_chip(conf);
}
/* Disable LPC */
pci_read_config_word(dev, LPC_EN, &tmpword); /* LPC_EN register */
tmpword &= 0xfffc; /* mask bit 1 and bit 0, COMA addr range disable */
pci_write_config_word(dev, LPC_EN, tmpword);
return ret;
/*
* Pre-configure a certain port on the ALi 1533 bridge.
* This is based on reverse-engineering since ALi does not
* provide any data sheet for the 1533 chip.
*/
static void __init preconfigure_ali_port(struct pci_dev *dev,
unsigned short port)
{
unsigned char reg;
/* These bits obviously control the different ports */
unsigned char mask;
unsigned char tmpbyte;
switch(port) {
case 0x0130:
case 0x0178:
reg = 0xb0;
mask = 0x80;
break;
case 0x03f8:
reg = 0xb4;
mask = 0x80;
break;
case 0x02f8:
reg = 0xb4;
mask = 0x30;
break;
case 0x02e8:
reg = 0xb4;
mask = 0x08;
break;
default:
IRDA_ERROR("Failed to configure unsupported port on ALi 1533 bridge: 0x%04x\n", port);
return;
}
pci_read_config_byte(dev, reg, &tmpbyte);
/* Turn on the right bits */
tmpbyte |= mask;
pci_write_config_byte(dev, reg, tmpbyte);
IRDA_MESSAGE("Activated ALi 1533 ISA bridge port 0x%04x.\n", port);
return;
}
static int __init preconfigure_through_ali(struct pci_dev *dev,
struct smsc_ircc_subsystem_configuration *conf)
struct
smsc_ircc_subsystem_configuration
*conf)
{
/* TODO: put in ALi 1533 configuration here. */
IRDA_MESSAGE("SORRY: %s has an unsupported bridge controller (ALi): not pre-configured.\n", conf->name);
return -ENODEV;
/* Configure the two ports on the ALi 1533 */
preconfigure_ali_port(dev, conf->sir_io);
preconfigure_ali_port(dev, conf->fir_io);
/* Pre-configure chip */
return preconfigure_smsc_chip(conf);
}
static int __init smsc_ircc_preconfigure_subsystems(unsigned short ircc_cfg,
@ -2552,9 +2756,10 @@ static int __init smsc_ircc_preconfigure_subsystems(unsigned short ircc_cfg,
struct smsc_ircc_subsystem_configuration *conf;
/*
* Cache the subsystem vendor/device: some manufacturers fail to set
* this for all components, so we save it in case there is just
* 0x0000 0x0000 on the device we want to check.
* Cache the subsystem vendor/device:
* some manufacturers fail to set this for all components,
* so we save it in case there is just 0x0000 0x0000 on the
* device we want to check.
*/
if (dev->subsystem_vendor != 0x0000U) {
ss_vendor = dev->subsystem_vendor;
@ -2564,13 +2769,20 @@ static int __init smsc_ircc_preconfigure_subsystems(unsigned short ircc_cfg,
for( ; conf->subvendor; conf++) {
if(conf->vendor == dev->vendor &&
conf->device == dev->device &&
conf->subvendor == ss_vendor && /* Sometimes these are cached values */
(conf->subdevice == ss_device || conf->subdevice == 0xffff)) {
struct smsc_ircc_subsystem_configuration tmpconf;
conf->subvendor == ss_vendor &&
/* Sometimes these are cached values */
(conf->subdevice == ss_device ||
conf->subdevice == 0xffff)) {
struct smsc_ircc_subsystem_configuration
tmpconf;
memcpy(&tmpconf, conf, sizeof(struct smsc_ircc_subsystem_configuration));
memcpy(&tmpconf, conf,
sizeof(struct smsc_ircc_subsystem_configuration));
/* Override the default values with anything passed in as parameter */
/*
* Override the default values with anything
* passed in as parameter
*/
if (ircc_cfg != 0)
tmpconf.cfg_base = ircc_cfg;
if (ircc_fir != 0)

View File

@ -357,18 +357,20 @@ ixgb_probe(struct pci_dev *pdev,
if((err = pci_enable_device(pdev)))
return err;
if(!(err = pci_set_dma_mask(pdev, DMA_64BIT_MASK))) {
if(!(err = pci_set_dma_mask(pdev, DMA_64BIT_MASK)) &&
!(err = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK))) {
pci_using_dac = 1;
} else {
if((err = pci_set_dma_mask(pdev, DMA_32BIT_MASK))) {
if((err = pci_set_dma_mask(pdev, DMA_32BIT_MASK)) ||
(err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK))) {
IXGB_ERR("No usable DMA configuration, aborting\n");
return err;
goto err_dma_mask;
}
pci_using_dac = 0;
}
if((err = pci_request_regions(pdev, ixgb_driver_name)))
return err;
goto err_request_regions;
pci_set_master(pdev);
@ -502,6 +504,9 @@ err_ioremap:
free_netdev(netdev);
err_alloc_etherdev:
pci_release_regions(pdev);
err_request_regions:
err_dma_mask:
pci_disable_device(pdev);
return err;
}

View File

@ -281,10 +281,16 @@ static void mv643xx_eth_tx_timeout_task(struct net_device *dev)
{
struct mv643xx_private *mp = netdev_priv(dev);
netif_device_detach(dev);
if (!netif_running(dev))
return;
netif_stop_queue(dev);
eth_port_reset(mp->port_num);
eth_port_start(dev);
netif_device_attach(dev);
if (mp->tx_ring_size - mp->tx_desc_count >= MAX_DESCS_PER_SKB)
netif_wake_queue(dev);
}
/**
@ -552,9 +558,9 @@ static irqreturn_t mv643xx_eth_int_handler(int irq, void *dev_id,
#else
if (eth_int_cause & ETH_INT_CAUSE_RX)
mv643xx_eth_receive_queue(dev, INT_MAX);
#endif
if (eth_int_cause_ext & ETH_INT_CAUSE_TX)
mv643xx_eth_free_completed_tx_descs(dev);
#endif
/*
* If no real interrupt occured, exit.
@ -1186,7 +1192,12 @@ static int mv643xx_eth_start_xmit(struct sk_buff *skb, struct net_device *dev)
BUG_ON(netif_queue_stopped(dev));
BUG_ON(skb == NULL);
BUG_ON(mp->tx_ring_size - mp->tx_desc_count < MAX_DESCS_PER_SKB);
if (mp->tx_ring_size - mp->tx_desc_count < MAX_DESCS_PER_SKB) {
printk(KERN_ERR "%s: transmit with queue full\n", dev->name);
netif_stop_queue(dev);
return 1;
}
if (has_tiny_unaligned_frags(skb)) {
if ((skb_linearize(skb, GFP_ATOMIC) != 0)) {

View File

@ -238,7 +238,7 @@ static int full_duplex[MAX_UNITS];
#define NATSEMI_RX_LIMIT 2046 /* maximum supported by hardware */
/* These identify the driver base version and may not be removed. */
static char version[] __devinitdata =
static const char version[] __devinitdata =
KERN_INFO DRV_NAME " dp8381x driver, version "
DRV_VERSION ", " DRV_RELDATE "\n"
KERN_INFO " originally by Donald Becker <becker@scyld.com>\n"

View File

@ -1560,7 +1560,7 @@ static void ei_receive(struct net_device *dev)
static void ei_rx_overrun(struct net_device *dev)
{
axnet_dev_t *info = (axnet_dev_t *)dev;
axnet_dev_t *info = PRIV(dev);
long e8390_base = dev->base_addr;
unsigned char was_txing, must_resend = 0;
struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);

View File

@ -78,6 +78,8 @@ static const struct pci_device_id skge_id_table[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_GE) },
{ PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_YU) },
{ PCI_DEVICE(PCI_VENDOR_ID_DLINK, PCI_DEVICE_ID_DLINK_DGE510T), },
{ PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4b00) },
{ PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4b01) },
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4320) },
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x5005) }, /* Belkin */
{ PCI_DEVICE(PCI_VENDOR_ID_CNET, PCI_DEVICE_ID_CNET_GIGACARD) },

View File

@ -99,8 +99,6 @@ MODULE_PARM_DESC(disable_msi, "Disable Message Signaled Interrupt (MSI)");
static const struct pci_device_id sky2_id_table[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9000) },
{ PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9E00) },
{ PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4b00) },
{ PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4b01) },
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4340) },
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4341) },
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4342) },
@ -579,8 +577,8 @@ static void sky2_mac_init(struct sky2_hw *hw, unsigned port)
reg = gma_read16(hw, port, GM_PHY_ADDR);
gma_write16(hw, port, GM_PHY_ADDR, reg | GM_PAR_MIB_CLR);
for (i = 0; i < GM_MIB_CNT_SIZE; i++)
gma_read16(hw, port, GM_MIB_CNT_BASE + 8 * i);
for (i = GM_MIB_CNT_BASE; i <= GM_MIB_CNT_END; i += 4)
gma_read16(hw, port, i);
gma_write16(hw, port, GM_PHY_ADDR, reg);
/* transmit control */

View File

@ -1375,7 +1375,7 @@ enum {
GM_PHY_ADDR = 0x0088, /* 16 bit r/w GPHY Address Register */
/* MIB Counters */
GM_MIB_CNT_BASE = 0x0100, /* Base Address of MIB Counters */
GM_MIB_CNT_SIZE = 256,
GM_MIB_CNT_END = 0x025C, /* Last MIB counter */
};

View File

@ -335,7 +335,7 @@ do { \
/* These identify the driver base version and may not be removed. */
static char version[] __devinitdata =
static const char version[] __devinitdata =
KERN_INFO "starfire.c:v1.03 7/26/2000 Written by Donald Becker <becker@scyld.com>\n"
KERN_INFO " (unofficial 2.2/2.4 kernel port, version " DRV_VERSION ", " DRV_RELDATE ")\n";

View File

@ -134,7 +134,7 @@ static const int multicast_filter_limit = 32;
#include "typhoon.h"
#include "typhoon-firmware.h"
static char version[] __devinitdata =
static const char version[] __devinitdata =
"typhoon.c: version " DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
MODULE_AUTHOR("David Dillow <dave@thedillows.org>");

View File

@ -469,7 +469,7 @@ struct rhine_private {
struct sk_buff *tx_skbuff[TX_RING_SIZE];
dma_addr_t tx_skbuff_dma[TX_RING_SIZE];
/* Tx bounce buffers */
/* Tx bounce buffers (Rhine-I only) */
unsigned char *tx_buf[TX_RING_SIZE];
unsigned char *tx_bufs;
dma_addr_t tx_bufs_dma;
@ -1043,7 +1043,8 @@ static void alloc_tbufs(struct net_device* dev)
rp->tx_ring[i].desc_length = cpu_to_le32(TXDESC);
next += sizeof(struct tx_desc);
rp->tx_ring[i].next_desc = cpu_to_le32(next);
rp->tx_buf[i] = &rp->tx_bufs[i * PKT_BUF_SZ];
if (rp->quirks & rqRhineI)
rp->tx_buf[i] = &rp->tx_bufs[i * PKT_BUF_SZ];
}
rp->tx_ring[i-1].next_desc = cpu_to_le32(rp->tx_ring_dma);
@ -1091,7 +1092,7 @@ static void rhine_check_media(struct net_device *dev, unsigned int init_media)
}
/* Called after status of force_media possibly changed */
void rhine_set_carrier(struct mii_if_info *mii)
static void rhine_set_carrier(struct mii_if_info *mii)
{
if (mii->force_media) {
/* autoneg is off: Link is always assumed to be up */

View File

@ -410,103 +410,6 @@ config WAN_ROUTER_DRIVERS
If unsure, say N.
config VENDOR_SANGOMA
tristate "Sangoma WANPIPE(tm) multiprotocol cards"
depends on WAN_ROUTER_DRIVERS && WAN_ROUTER && (PCI || ISA) && BROKEN
---help---
Driver for S514-PCI/ISA Synchronous Data Link Adapters (SDLA).
WANPIPE from Sangoma Technologies Inc. <http://www.sangoma.com/>
is a family of intelligent multiprotocol WAN adapters with data
transfer rates up to 4Mbps. Cards support:
- X.25, Frame Relay, PPP, Cisco HDLC protocols.
- API for protocols like HDLC (LAPB), HDLC Streaming, X.25,
Frame Relay and BiSync.
- Ethernet Bridging over Frame Relay protocol.
- MULTILINK PPP
- Async PPP (Modem Dialup)
The next questions will ask you about the protocols you want
the driver to support.
If you have one or more of these cards, say M to this option;
and read <file:Documentation/networking/wan-router.txt>.
To compile this driver as a module, choose M here: the
module will be called wanpipe.
config WANPIPE_CHDLC
bool "WANPIPE Cisco HDLC support"
depends on VENDOR_SANGOMA
---help---
Connect a WANPIPE card to a leased line using the Cisco HDLC.
- Supports Dual Port Cisco HDLC on the S514-PCI/S508-ISA cards
which allows user to build applications using the HDLC streaming API.
- CHDLC Streaming MULTILINK PPP that can bind multiple WANPIPE T1
cards into a single logical channel.
Say Y and the Cisco HDLC support, HDLC streaming API and
MULTILINK PPP will be included in the driver.
config WANPIPE_FR
bool "WANPIPE Frame Relay support"
depends on VENDOR_SANGOMA
help
Connect a WANPIPE card to a Frame Relay network, or use Frame Relay
API to develop custom applications.
Contains the Ethernet Bridging over Frame Relay feature, where
a WANPIPE frame relay link can be directly connected to the Linux
kernel bridge. The Frame Relay option is supported on S514-PCI
and S508-ISA cards.
Say Y and the Frame Relay support will be included in the driver.
config WANPIPE_X25
bool "WANPIPE X.25 support"
depends on VENDOR_SANGOMA
help
Connect a WANPIPE card to an X.25 network.
Includes the X.25 API support for custom applications over the
X.25 protocol. The X.25 option is supported on S514-PCI and
S508-ISA cards.
Say Y and the X.25 support will be included in the driver.
config WANPIPE_PPP
bool "WANPIPE PPP support"
depends on VENDOR_SANGOMA
help
Connect a WANPIPE card to a leased line using Point-to-Point
Protocol (PPP).
The PPP option is supported on S514-PCI/S508-ISA cards.
Say Y and the PPP support will be included in the driver.
config WANPIPE_MULTPPP
bool "WANPIPE Multi-Port PPP support"
depends on VENDOR_SANGOMA
help
Connect a WANPIPE card to a leased line using Point-to-Point
Protocol (PPP).
Uses in-kernel SyncPPP protocol over the Sangoma HDLC Streaming
adapter. In this case each Sangoma adapter port can support an
independent PPP connection. For example, a single Quad-Port PCI
adapter can support up to four independent PPP links. The PPP
option is supported on S514-PCI/S508-ISA cards.
Say Y and the Multi-Port PPP support will be included in the driver.
config CYCLADES_SYNC
tristate "Cyclom 2X(tm) cards (EXPERIMENTAL)"
depends on WAN_ROUTER_DRIVERS && (PCI || ISA)

View File

@ -5,14 +5,6 @@
# Rewritten to use lists instead of if-statements.
#
wanpipe-y := sdlamain.o sdla_ft1.o
wanpipe-$(CONFIG_WANPIPE_X25) += sdla_x25.o
wanpipe-$(CONFIG_WANPIPE_FR) += sdla_fr.o
wanpipe-$(CONFIG_WANPIPE_CHDLC) += sdla_chdlc.o
wanpipe-$(CONFIG_WANPIPE_PPP) += sdla_ppp.o
wanpipe-$(CONFIG_WANPIPE_MULTPPP) += wanpipe_multppp.o
wanpipe-objs := $(wanpipe-y)
cyclomx-y := cycx_main.o
cyclomx-$(CONFIG_CYCLOMX_X25) += cycx_x25.o
cyclomx-objs := $(cyclomx-y)
@ -43,11 +35,6 @@ obj-$(CONFIG_LANMEDIA) += lmc/
obj-$(CONFIG_DLCI) += dlci.o
obj-$(CONFIG_SDLA) += sdla.o
ifeq ($(CONFIG_WANPIPE_MULTPPP),y)
obj-$(CONFIG_VENDOR_SANGOMA) += sdladrv.o wanpipe.o syncppp.o
else
obj-$(CONFIG_VENDOR_SANGOMA) += sdladrv.o wanpipe.o
endif
obj-$(CONFIG_CYCLADES_SYNC) += cycx_drv.o cyclomx.o
obj-$(CONFIG_LAPBETHER) += lapbether.o
obj-$(CONFIG_SBNI) += sbni.o

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,345 +0,0 @@
/*****************************************************************************
* sdla_chdlc.c WANPIPE(tm) Multiprotocol WAN Link Driver. Cisco HDLC module.
*
* Authors: Nenad Corbic <ncorbic@sangoma.com>
* Gideon Hack
*
* Copyright: (c) 1995-1999 Sangoma Technologies Inc.
*
* 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.
* ============================================================================
* Sep 30, 1999 Nenad Corbic Fixed dynamic IP and route setup.
* Sep 23, 1999 Nenad Corbic Added SMP support, fixed tracing
* Sep 13, 1999 Nenad Corbic Split up Port 0 and 1 into separate devices.
* Jun 02, 1999 Gideon Hack Added support for the S514 adapter.
* Oct 30, 1998 Jaspreet Singh Added Support for CHDLC API (HDLC STREAMING).
* Oct 28, 1998 Jaspreet Singh Added Support for Dual Port CHDLC.
* Aug 07, 1998 David Fong Initial version.
*****************************************************************************/
#include <linux/module.h>
#include <linux/kernel.h> /* printk(), and other useful stuff */
#include <linux/stddef.h> /* offsetof(), etc. */
#include <linux/errno.h> /* return codes */
#include <linux/string.h> /* inline memset(), etc. */
#include <linux/slab.h> /* kmalloc(), kfree() */
#include <linux/wanrouter.h> /* WAN router definitions */
#include <linux/wanpipe.h> /* WANPIPE common user API definitions */
#include <linux/if_arp.h> /* ARPHRD_* defines */
#include <linux/jiffies.h> /* time_after() macro */
#include <linux/inetdevice.h>
#include <asm/uaccess.h>
#include <linux/in.h> /* sockaddr_in */
#include <linux/inet.h>
#include <linux/if.h>
#include <asm/byteorder.h> /* htons(), etc. */
#include <linux/sdlapci.h>
#include <asm/io.h>
#include <linux/sdla_chdlc.h> /* CHDLC firmware API definitions */
/****** Defines & Macros ****************************************************/
/* reasons for enabling the timer interrupt on the adapter */
#define TMR_INT_ENABLED_UDP 0x0001
#define TMR_INT_ENABLED_UPDATE 0x0002
#define CHDLC_DFLT_DATA_LEN 1500 /* default MTU */
#define CHDLC_HDR_LEN 1
#define IFF_POINTTOPOINT 0x10
#define WANPIPE 0x00
#define API 0x01
#define CHDLC_API 0x01
#define PORT(x) (x == 0 ? "PRIMARY" : "SECONDARY" )
/******Data Structures*****************************************************/
/* This structure is placed in the private data area of the device structure.
* The card structure used to occupy the private area but now the following
* structure will incorporate the card structure along with CHDLC specific data
*/
typedef struct chdlc_private_area
{
struct net_device *slave;
sdla_t *card;
int TracingEnabled; /* For enabling Tracing */
unsigned long curr_trace_addr; /* Used for Tracing */
unsigned long start_trace_addr;
unsigned long end_trace_addr;
unsigned long base_addr_trace_buffer;
unsigned long end_addr_trace_buffer;
unsigned short number_trace_elements;
unsigned available_buffer_space;
unsigned long router_start_time;
unsigned char route_status;
unsigned char route_removed;
unsigned long tick_counter; /* For 5s timeout counter */
unsigned long router_up_time;
u32 IP_address; /* IP addressing */
u32 IP_netmask;
unsigned char mc; /* Mulitcast support on/off */
unsigned short udp_pkt_lgth; /* udp packet processing */
char udp_pkt_src;
char udp_pkt_data[MAX_LGTH_UDP_MGNT_PKT];
unsigned short timer_int_enabled;
char update_comms_stats; /* updating comms stats */
//FIXME: add driver stats as per frame relay!
} chdlc_private_area_t;
/* Route Status options */
#define NO_ROUTE 0x00
#define ADD_ROUTE 0x01
#define ROUTE_ADDED 0x02
#define REMOVE_ROUTE 0x03
/****** Function Prototypes *************************************************/
/* WAN link driver entry points. These are called by the WAN router module. */
static int wpft1_exec (struct sdla *card, void *u_cmd, void *u_data);
static int chdlc_read_version (sdla_t* card, char* str);
static int chdlc_error (sdla_t *card, int err, CHDLC_MAILBOX_STRUCT *mb);
/****** Public Functions ****************************************************/
/*============================================================================
* Cisco HDLC protocol initialization routine.
*
* This routine is called by the main WANPIPE module during setup. At this
* point adapter is completely initialized and firmware is running.
* o read firmware version (to make sure it's alive)
* o configure adapter
* o initialize protocol-specific fields of the adapter data space.
*
* Return: 0 o.k.
* < 0 failure.
*/
int wpft1_init (sdla_t* card, wandev_conf_t* conf)
{
unsigned char port_num;
int err;
union
{
char str[80];
} u;
volatile CHDLC_MAILBOX_STRUCT* mb;
CHDLC_MAILBOX_STRUCT* mb1;
unsigned long timeout;
/* Verify configuration ID */
if (conf->config_id != WANCONFIG_CHDLC) {
printk(KERN_INFO "%s: invalid configuration ID %u!\n",
card->devname, conf->config_id);
return -EINVAL;
}
/* Use primary port */
card->u.c.comm_port = 0;
/* Initialize protocol-specific fields */
if(card->hw.type != SDLA_S514){
card->mbox = (void *) card->hw.dpmbase;
}else{
card->mbox = (void *) card->hw.dpmbase + PRI_BASE_ADDR_MB_STRUCT;
}
mb = mb1 = card->mbox;
if (!card->configured){
/* The board will place an 'I' in the return code to indicate that it is
ready to accept commands. We expect this to be completed in less
than 1 second. */
timeout = jiffies;
while (mb->return_code != 'I') /* Wait 1s for board to initialize */
if (time_after(jiffies, timeout + 1*HZ)) break;
if (mb->return_code != 'I') {
printk(KERN_INFO
"%s: Initialization not completed by adapter\n",
card->devname);
printk(KERN_INFO "Please contact Sangoma representative.\n");
return -EIO;
}
}
/* Read firmware version. Note that when adapter initializes, it
* clears the mailbox, so it may appear that the first command was
* executed successfully when in fact it was merely erased. To work
* around this, we execute the first command twice.
*/
if (chdlc_read_version(card, u.str))
return -EIO;
printk(KERN_INFO "%s: Running FT1 Configuration firmware v%s\n",
card->devname, u.str);
card->isr = NULL;
card->poll = NULL;
card->exec = &wpft1_exec;
card->wandev.update = NULL;
card->wandev.new_if = NULL;
card->wandev.del_if = NULL;
card->wandev.state = WAN_DUALPORT;
card->wandev.udp_port = conf->udp_port;
card->wandev.new_if_cnt = 0;
/* This is for the ports link state */
card->u.c.state = WAN_DISCONNECTED;
/* reset the number of times the 'update()' proc has been called */
card->u.c.update_call_count = 0;
card->wandev.ttl = 0x7F;
card->wandev.interface = 0;
card->wandev.clocking = 0;
port_num = card->u.c.comm_port;
/* Setup Port Bps */
card->wandev.bps = 0;
card->wandev.mtu = MIN_LGTH_CHDLC_DATA_CFG;
/* Set up the interrupt status area */
/* Read the CHDLC Configuration and obtain:
* Ptr to shared memory infor struct
* Use this pointer to calculate the value of card->u.c.flags !
*/
mb1->buffer_length = 0;
mb1->command = READ_CHDLC_CONFIGURATION;
err = sdla_exec(mb1) ? mb1->return_code : CMD_TIMEOUT;
if(err != COMMAND_OK) {
chdlc_error(card, err, mb1);
return -EIO;
}
if(card->hw.type == SDLA_S514){
card->u.c.flags = (void *)(card->hw.dpmbase +
(((CHDLC_CONFIGURATION_STRUCT *)mb1->data)->
ptr_shared_mem_info_struct));
}else{
card->u.c.flags = (void *)(card->hw.dpmbase +
(((CHDLC_CONFIGURATION_STRUCT *)mb1->data)->
ptr_shared_mem_info_struct % SDLA_WINDOWSIZE));
}
card->wandev.state = WAN_FT1_READY;
printk(KERN_INFO "%s: FT1 Config Ready !\n",card->devname);
return 0;
}
static int wpft1_exec(sdla_t *card, void *u_cmd, void *u_data)
{
CHDLC_MAILBOX_STRUCT* mbox = card->mbox;
int len;
if (copy_from_user((void*)&mbox->command, u_cmd, sizeof(ft1_exec_cmd_t))){
return -EFAULT;
}
len = mbox->buffer_length;
if (len) {
if( copy_from_user((void*)&mbox->data, u_data, len)){
return -EFAULT;
}
}
/* execute command */
if (!sdla_exec(mbox)){
return -EIO;
}
/* return result */
if( copy_to_user(u_cmd, (void*)&mbox->command, sizeof(ft1_exec_cmd_t))){
return -EFAULT;
}
len = mbox->buffer_length;
if (len && u_data && copy_to_user(u_data, (void*)&mbox->data, len)){
return -EFAULT;
}
return 0;
}
/*============================================================================
* Read firmware code version.
* Put code version as ASCII string in str.
*/
static int chdlc_read_version (sdla_t* card, char* str)
{
CHDLC_MAILBOX_STRUCT* mb = card->mbox;
int len;
char err;
mb->buffer_length = 0;
mb->command = READ_CHDLC_CODE_VERSION;
err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
if(err != COMMAND_OK) {
chdlc_error(card,err,mb);
}
else if (str) { /* is not null */
len = mb->buffer_length;
memcpy(str, mb->data, len);
str[len] = '\0';
}
return (err);
}
/*============================================================================
* Firmware error handler.
* This routine is called whenever firmware command returns non-zero
* return code.
*
* Return zero if previous command has to be cancelled.
*/
static int chdlc_error (sdla_t *card, int err, CHDLC_MAILBOX_STRUCT *mb)
{
unsigned cmd = mb->command;
switch (err) {
case CMD_TIMEOUT:
printk(KERN_ERR "%s: command 0x%02X timed out!\n",
card->devname, cmd);
break;
case S514_BOTH_PORTS_SAME_CLK_MODE:
if(cmd == SET_CHDLC_CONFIGURATION) {
printk(KERN_INFO
"%s: Configure both ports for the same clock source\n",
card->devname);
break;
}
default:
printk(KERN_INFO "%s: command 0x%02X returned 0x%02X!\n",
card->devname, cmd, err);
}
return 0;
}
MODULE_LICENSE("GPL");

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -360,9 +360,6 @@ static int __init rpaphp_init(void)
while ((dn = of_find_node_by_type(dn, "pci")))
rpaphp_add_slot(dn);
if (!num_slots)
return -ENODEV;
return 0;
}

View File

@ -504,6 +504,201 @@ void pci_scan_msi_device(struct pci_dev *dev)
nr_reserved_vectors++;
}
#ifdef CONFIG_PM
int pci_save_msi_state(struct pci_dev *dev)
{
int pos, i = 0;
u16 control;
struct pci_cap_saved_state *save_state;
u32 *cap;
pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
if (pos <= 0 || dev->no_msi)
return 0;
pci_read_config_word(dev, msi_control_reg(pos), &control);
if (!(control & PCI_MSI_FLAGS_ENABLE))
return 0;
save_state = kzalloc(sizeof(struct pci_cap_saved_state) + sizeof(u32) * 5,
GFP_KERNEL);
if (!save_state) {
printk(KERN_ERR "Out of memory in pci_save_msi_state\n");
return -ENOMEM;
}
cap = &save_state->data[0];
pci_read_config_dword(dev, pos, &cap[i++]);
control = cap[0] >> 16;
pci_read_config_dword(dev, pos + PCI_MSI_ADDRESS_LO, &cap[i++]);
if (control & PCI_MSI_FLAGS_64BIT) {
pci_read_config_dword(dev, pos + PCI_MSI_ADDRESS_HI, &cap[i++]);
pci_read_config_dword(dev, pos + PCI_MSI_DATA_64, &cap[i++]);
} else
pci_read_config_dword(dev, pos + PCI_MSI_DATA_32, &cap[i++]);
if (control & PCI_MSI_FLAGS_MASKBIT)
pci_read_config_dword(dev, pos + PCI_MSI_MASK_BIT, &cap[i++]);
disable_msi_mode(dev, pos, PCI_CAP_ID_MSI);
save_state->cap_nr = PCI_CAP_ID_MSI;
pci_add_saved_cap(dev, save_state);
return 0;
}
void pci_restore_msi_state(struct pci_dev *dev)
{
int i = 0, pos;
u16 control;
struct pci_cap_saved_state *save_state;
u32 *cap;
save_state = pci_find_saved_cap(dev, PCI_CAP_ID_MSI);
pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
if (!save_state || pos <= 0)
return;
cap = &save_state->data[0];
control = cap[i++] >> 16;
pci_write_config_dword(dev, pos + PCI_MSI_ADDRESS_LO, cap[i++]);
if (control & PCI_MSI_FLAGS_64BIT) {
pci_write_config_dword(dev, pos + PCI_MSI_ADDRESS_HI, cap[i++]);
pci_write_config_dword(dev, pos + PCI_MSI_DATA_64, cap[i++]);
} else
pci_write_config_dword(dev, pos + PCI_MSI_DATA_32, cap[i++]);
if (control & PCI_MSI_FLAGS_MASKBIT)
pci_write_config_dword(dev, pos + PCI_MSI_MASK_BIT, cap[i++]);
pci_write_config_word(dev, pos + PCI_MSI_FLAGS, control);
enable_msi_mode(dev, pos, PCI_CAP_ID_MSI);
pci_remove_saved_cap(save_state);
kfree(save_state);
}
int pci_save_msix_state(struct pci_dev *dev)
{
int pos;
u16 control;
struct pci_cap_saved_state *save_state;
pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
if (pos <= 0 || dev->no_msi)
return 0;
pci_read_config_word(dev, msi_control_reg(pos), &control);
if (!(control & PCI_MSIX_FLAGS_ENABLE))
return 0;
save_state = kzalloc(sizeof(struct pci_cap_saved_state) + sizeof(u16),
GFP_KERNEL);
if (!save_state) {
printk(KERN_ERR "Out of memory in pci_save_msix_state\n");
return -ENOMEM;
}
*((u16 *)&save_state->data[0]) = control;
disable_msi_mode(dev, pos, PCI_CAP_ID_MSIX);
save_state->cap_nr = PCI_CAP_ID_MSIX;
pci_add_saved_cap(dev, save_state);
return 0;
}
void pci_restore_msix_state(struct pci_dev *dev)
{
u16 save;
int pos;
int vector, head, tail = 0;
void __iomem *base;
int j;
struct msg_address address;
struct msg_data data;
struct msi_desc *entry;
int temp;
struct pci_cap_saved_state *save_state;
save_state = pci_find_saved_cap(dev, PCI_CAP_ID_MSIX);
if (!save_state)
return;
save = *((u16 *)&save_state->data[0]);
pci_remove_saved_cap(save_state);
kfree(save_state);
pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
if (pos <= 0)
return;
/* route the table */
temp = dev->irq;
if (msi_lookup_vector(dev, PCI_CAP_ID_MSIX))
return;
vector = head = dev->irq;
while (head != tail) {
entry = msi_desc[vector];
base = entry->mask_base;
j = entry->msi_attrib.entry_nr;
msi_address_init(&address);
msi_data_init(&data, vector);
address.lo_address.value &= MSI_ADDRESS_DEST_ID_MASK;
address.lo_address.value |= entry->msi_attrib.current_cpu <<
MSI_TARGET_CPU_SHIFT;
writel(address.lo_address.value,
base + j * PCI_MSIX_ENTRY_SIZE +
PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET);
writel(address.hi_address,
base + j * PCI_MSIX_ENTRY_SIZE +
PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET);
writel(*(u32*)&data,
base + j * PCI_MSIX_ENTRY_SIZE +
PCI_MSIX_ENTRY_DATA_OFFSET);
tail = msi_desc[vector]->link.tail;
vector = tail;
}
dev->irq = temp;
pci_write_config_word(dev, msi_control_reg(pos), save);
enable_msi_mode(dev, pos, PCI_CAP_ID_MSIX);
}
#endif
static void msi_register_init(struct pci_dev *dev, struct msi_desc *entry)
{
struct msg_address address;
struct msg_data data;
int pos, vector = dev->irq;
u16 control;
pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
pci_read_config_word(dev, msi_control_reg(pos), &control);
/* Configure MSI capability structure */
msi_address_init(&address);
msi_data_init(&data, vector);
entry->msi_attrib.current_cpu = ((address.lo_address.u.dest_id >>
MSI_TARGET_CPU_SHIFT) & MSI_TARGET_CPU_MASK);
pci_write_config_dword(dev, msi_lower_address_reg(pos),
address.lo_address.value);
if (is_64bit_address(control)) {
pci_write_config_dword(dev,
msi_upper_address_reg(pos), address.hi_address);
pci_write_config_word(dev,
msi_data_reg(pos, 1), *((u32*)&data));
} else
pci_write_config_word(dev,
msi_data_reg(pos, 0), *((u32*)&data));
if (entry->msi_attrib.maskbit) {
unsigned int maskbits, temp;
/* All MSIs are unmasked by default, Mask them all */
pci_read_config_dword(dev,
msi_mask_bits_reg(pos, is_64bit_address(control)),
&maskbits);
temp = (1 << multi_msi_capable(control));
temp = ((temp - 1) & ~temp);
maskbits |= temp;
pci_write_config_dword(dev,
msi_mask_bits_reg(pos, is_64bit_address(control)),
maskbits);
}
}
/**
* msi_capability_init - configure device's MSI capability structure
* @dev: pointer to the pci_dev data structure of MSI device function
@ -516,8 +711,6 @@ void pci_scan_msi_device(struct pci_dev *dev)
static int msi_capability_init(struct pci_dev *dev)
{
struct msi_desc *entry;
struct msg_address address;
struct msg_data data;
int pos, vector;
u16 control;
@ -549,33 +742,8 @@ static int msi_capability_init(struct pci_dev *dev)
/* Replace with MSI handler */
irq_handler_init(PCI_CAP_ID_MSI, vector, entry->msi_attrib.maskbit);
/* Configure MSI capability structure */
msi_address_init(&address);
msi_data_init(&data, vector);
entry->msi_attrib.current_cpu = ((address.lo_address.u.dest_id >>
MSI_TARGET_CPU_SHIFT) & MSI_TARGET_CPU_MASK);
pci_write_config_dword(dev, msi_lower_address_reg(pos),
address.lo_address.value);
if (is_64bit_address(control)) {
pci_write_config_dword(dev,
msi_upper_address_reg(pos), address.hi_address);
pci_write_config_word(dev,
msi_data_reg(pos, 1), *((u32*)&data));
} else
pci_write_config_word(dev,
msi_data_reg(pos, 0), *((u32*)&data));
if (entry->msi_attrib.maskbit) {
unsigned int maskbits, temp;
/* All MSIs are unmasked by default, Mask them all */
pci_read_config_dword(dev,
msi_mask_bits_reg(pos, is_64bit_address(control)),
&maskbits);
temp = (1 << multi_msi_capable(control));
temp = ((temp - 1) & ~temp);
maskbits |= temp;
pci_write_config_dword(dev,
msi_mask_bits_reg(pos, is_64bit_address(control)),
maskbits);
}
msi_register_init(dev, entry);
attach_msi_entry(entry, vector);
/* Set MSI enabled bits */
enable_msi_mode(dev, pos, PCI_CAP_ID_MSI);
@ -731,6 +899,7 @@ int pci_enable_msi(struct pci_dev* dev)
vector_irq[dev->irq] = -1;
nr_released_vectors--;
spin_unlock_irqrestore(&msi_lock, flags);
msi_register_init(dev, msi_desc[dev->irq]);
enable_msi_mode(dev, pos, PCI_CAP_ID_MSI);
return 0;
}

View File

@ -271,10 +271,12 @@ static int pci_device_suspend(struct device * dev, pm_message_t state)
struct pci_driver * drv = pci_dev->driver;
int i = 0;
if (drv && drv->suspend)
if (drv && drv->suspend) {
i = drv->suspend(pci_dev, state);
else
suspend_report_result(drv->suspend, i);
} else {
pci_save_state(pci_dev);
}
return i;
}

View File

@ -307,9 +307,11 @@ pci_set_power_state(struct pci_dev *dev, pci_power_t state)
* Can enter D0 from any state, but if we can only go deeper
* to sleep if we're already in a low power state
*/
if (state != PCI_D0 && dev->current_state > state)
if (state != PCI_D0 && dev->current_state > state) {
printk(KERN_ERR "%s(): %s: state=%d, current state=%d\n",
__FUNCTION__, pci_name(dev), state, dev->current_state);
return -EINVAL;
else if (dev->current_state == state)
} else if (dev->current_state == state)
return 0; /* we're already there */
/* find PCI PM capability in list */
@ -444,6 +446,10 @@ pci_save_state(struct pci_dev *dev)
/* XXX: 100% dword access ok here? */
for (i = 0; i < 16; i++)
pci_read_config_dword(dev, i * 4,&dev->saved_config_space[i]);
if ((i = pci_save_msi_state(dev)) != 0)
return i;
if ((i = pci_save_msix_state(dev)) != 0)
return i;
return 0;
}
@ -458,6 +464,8 @@ pci_restore_state(struct pci_dev *dev)
for (i = 0; i < 16; i++)
pci_write_config_dword(dev,i * 4, dev->saved_config_space[i]);
pci_restore_msi_state(dev);
pci_restore_msix_state(dev);
return 0;
}

View File

@ -55,6 +55,17 @@ void pci_no_msi(void);
static inline void disable_msi_mode(struct pci_dev *dev, int pos, int type) { }
static inline void pci_no_msi(void) { }
#endif
#if defined(CONFIG_PCI_MSI) && defined(CONFIG_PM)
int pci_save_msi_state(struct pci_dev *dev);
int pci_save_msix_state(struct pci_dev *dev);
void pci_restore_msi_state(struct pci_dev *dev);
void pci_restore_msix_state(struct pci_dev *dev);
#else
static inline int pci_save_msi_state(struct pci_dev *dev) { return 0; }
static inline int pci_save_msix_state(struct pci_dev *dev) { return 0; }
static inline void pci_restore_msi_state(struct pci_dev *dev) {}
static inline void pci_restore_msix_state(struct pci_dev *dev) {}
#endif
extern int pcie_mch_quirk;
extern struct device_attribute pci_dev_attrs[];

View File

@ -592,7 +592,7 @@ static void __init quirk_amd_8131_ioapic(struct pci_dev *dev)
pci_write_config_byte( dev, AMD8131_MISC, tmp);
}
}
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_APIC, quirk_amd_8131_ioapic );
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_amd_8131_ioapic);
static void __init quirk_svw_msi(struct pci_dev *dev)
{
@ -921,6 +921,7 @@ static void __init asus_hides_smbus_hostbridge(struct pci_dev *dev)
if (dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB) {
switch (dev->subsystem_device) {
case 0x1882: /* M6V notebook */
case 0x1977: /* A6VA notebook */
asus_hides_smbus = 1;
}
}
@ -999,6 +1000,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0, asu
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12, asus_hides_smbus_lpc );
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12, asus_hides_smbus_lpc );
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0, asus_hides_smbus_lpc );
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, asus_hides_smbus_lpc );
static void __init asus_hides_smbus_lpc_ich6(struct pci_dev *dev)
{

View File

@ -28,8 +28,6 @@
#include <asm/arch/gpio.h>
#define CF_SIZE 0x30000000 /* CS5+CS6: unavailable */
/*
* A0..A10 work in each range; A23 indicates I/O space; A25 is CFRNW;
* some other bit in {A24,A22..A11} is nREG to flag memory access
@ -76,7 +74,8 @@ static irqreturn_t at91_cf_irq(int irq, void *_cf, struct pt_regs *r)
/* kick pccard as needed */
if (present != cf->present) {
cf->present = present;
pr_debug("%s: card %s\n", driver_name, present ? "present" : "gone");
pr_debug("%s: card %s\n", driver_name,
present ? "present" : "gone");
pcmcia_parse_events(&cf->socket, SS_DETECT);
}
}
@ -93,7 +92,7 @@ static int at91_cf_get_status(struct pcmcia_socket *s, u_int *sp)
cf = container_of(s, struct at91_cf_socket, socket);
/* NOTE: we assume 3VCARD, not XVCARD... */
/* NOTE: CF is always 3VCARD */
if (at91_cf_present(cf)) {
int rdy = cf->board->irq_pin; /* RDY/nIRQ */
int vcc = cf->board->vcc_pin;
@ -109,7 +108,8 @@ static int at91_cf_get_status(struct pcmcia_socket *s, u_int *sp)
return 0;
}
static int at91_cf_set_socket(struct pcmcia_socket *sock, struct socket_state_t *s)
static int
at91_cf_set_socket(struct pcmcia_socket *sock, struct socket_state_t *s)
{
struct at91_cf_socket *cf;
@ -184,7 +184,8 @@ static int at91_cf_set_io_map(struct pcmcia_socket *s, struct pccard_io_map *io)
}
/* pcmcia layer maps/unmaps mem regions */
static int at91_cf_set_mem_map(struct pcmcia_socket *s, struct pccard_mem_map *map)
static int
at91_cf_set_mem_map(struct pcmcia_socket *s, struct pccard_mem_map *map)
{
struct at91_cf_socket *cf;
@ -218,12 +219,17 @@ static int __init at91_cf_probe(struct device *dev)
struct at91_cf_socket *cf;
struct at91_cf_data *board = dev->platform_data;
struct platform_device *pdev = to_platform_device(dev);
struct resource *io;
unsigned int csa;
int status;
if (!board || !board->det_pin || !board->rst_pin)
return -ENODEV;
io = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!io)
return -ENODEV;
cf = kcalloc(1, sizeof *cf, GFP_KERNEL);
if (!cf)
return -ENOMEM;
@ -250,10 +256,14 @@ static int __init at91_cf_probe(struct device *dev)
* REVISIT: these timings are in terms of MCK cycles, so
* when MCK changes (cpufreq etc) so must these values...
*/
at91_sys_write(AT91_SMC_CSR(4), AT91_SMC_ACSS_STD | AT91_SMC_DBW_16 | AT91_SMC_BAT | AT91_SMC_WSEN
| AT91_SMC_NWS_(32) /* wait states */
| AT91_SMC_RWSETUP_(6) /* setup time */
| AT91_SMC_RWHOLD_(4) /* hold time */
at91_sys_write(AT91_SMC_CSR(4),
AT91_SMC_ACSS_STD
| AT91_SMC_DBW_16
| AT91_SMC_BAT
| AT91_SMC_WSEN
| AT91_SMC_NWS_(32) /* wait states */
| AT91_SMC_RWSETUP_(6) /* setup time */
| AT91_SMC_RWHOLD_(4) /* hold time */
);
/* must be a GPIO; ergo must trigger on both edges */
@ -274,8 +284,7 @@ static int __init at91_cf_probe(struct device *dev)
if (status < 0)
goto fail0a;
cf->socket.pci_irq = board->irq_pin;
}
else
} else
cf->socket.pci_irq = NR_IRQS + 1;
/* pcmcia layer only remaps "real" memory not iospace */
@ -284,7 +293,8 @@ static int __init at91_cf_probe(struct device *dev)
goto fail1;
/* reserve CS4, CS5, and CS6 regions; but use just CS4 */
if (!request_mem_region(AT91_CF_BASE, CF_SIZE, driver_name))
if (!request_mem_region(io->start, io->end + 1 - io->start,
driver_name))
goto fail1;
pr_info("%s: irqs det #%d, io #%d\n", driver_name,
@ -297,7 +307,7 @@ static int __init at91_cf_probe(struct device *dev)
cf->socket.features = SS_CAP_PCCARD | SS_CAP_STATIC_MAP
| SS_CAP_MEM_ALIGN;
cf->socket.map_size = SZ_2K;
cf->socket.io[0].NumPorts = SZ_2K;
cf->socket.io[0].res = io;
status = pcmcia_register_socket(&cf->socket);
if (status < 0)
@ -307,7 +317,7 @@ static int __init at91_cf_probe(struct device *dev)
fail2:
iounmap((void __iomem *) cf->socket.io_offset);
release_mem_region(AT91_CF_BASE, CF_SIZE);
release_mem_region(io->start, io->end + 1 - io->start);
fail1:
if (board->irq_pin)
free_irq(board->irq_pin, cf);
@ -321,14 +331,15 @@ fail0:
static int __exit at91_cf_remove(struct device *dev)
{
struct at91_cf_socket *cf = dev_get_drvdata(dev);
unsigned int csa;
struct at91_cf_socket *cf = dev_get_drvdata(dev);
struct resource *io = cf->socket.io[0].res;
unsigned int csa;
pcmcia_unregister_socket(&cf->socket);
free_irq(cf->board->irq_pin, cf);
free_irq(cf->board->det_pin, cf);
iounmap((void __iomem *) cf->socket.io_offset);
release_mem_region(AT91_CF_BASE, CF_SIZE);
release_mem_region(io->start, io->end + 1 - io->start);
csa = at91_sys_read(AT91_EBI_CSA);
at91_sys_write(AT91_EBI_CSA, csa & ~AT91_EBI_CS4A);
@ -342,8 +353,8 @@ static struct device_driver at91_cf_driver = {
.bus = &platform_bus_type,
.probe = at91_cf_probe,
.remove = __exit_p(at91_cf_remove),
.suspend = pcmcia_socket_dev_suspend,
.resume = pcmcia_socket_dev_resume,
.suspend = pcmcia_socket_dev_suspend,
.resume = pcmcia_socket_dev_resume,
};
/*--------------------------------------------------------------------------*/

View File

@ -65,6 +65,7 @@
2.26.02.005 - Fix use_sg == 0 mapping on systems with 4GB or higher.
2.26.02.006 - Fix 9550SX pchip reset timeout.
Add big endian support.
2.26.02.007 - Disable local interrupts during kmap/unmap_atomic().
*/
#include <linux/module.h>
@ -88,7 +89,7 @@
#include "3w-9xxx.h"
/* Globals */
#define TW_DRIVER_VERSION "2.26.02.006"
#define TW_DRIVER_VERSION "2.26.02.007"
static TW_Device_Extension *twa_device_extension_list[TW_MAX_SLOT];
static unsigned int twa_device_extension_count;
static int twa_major = -1;
@ -1942,9 +1943,13 @@ static void twa_scsiop_execute_scsi_complete(TW_Device_Extension *tw_dev, int re
}
if (tw_dev->srb[request_id]->use_sg == 1) {
struct scatterlist *sg = (struct scatterlist *)tw_dev->srb[request_id]->request_buffer;
char *buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
char *buf;
unsigned long flags = 0;
local_irq_save(flags);
buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
memcpy(buf, tw_dev->generic_buffer_virt[request_id], sg->length);
kunmap_atomic(buf - sg->offset, KM_IRQ0);
local_irq_restore(flags);
}
}
} /* End twa_scsiop_execute_scsi_complete() */

View File

@ -1079,7 +1079,7 @@ config SCSI_SYM53C8XX_DMA_ADDRESSING_MODE
memory using PCI DAC cycles.
config SCSI_SYM53C8XX_DEFAULT_TAGS
int "default tagged command queue depth"
int "Default tagged command queue depth"
depends on SCSI_SYM53C8XX_2
default "16"
help
@ -1090,7 +1090,7 @@ config SCSI_SYM53C8XX_DEFAULT_TAGS
exceed CONFIG_SCSI_SYM53C8XX_MAX_TAGS.
config SCSI_SYM53C8XX_MAX_TAGS
int "maximum number of queued commands"
int "Maximum number of queued commands"
depends on SCSI_SYM53C8XX_2
default "64"
help
@ -1099,13 +1099,14 @@ config SCSI_SYM53C8XX_MAX_TAGS
possible. The driver supports up to 256 queued commands per device.
This value is used as a compiled-in hard limit.
config SCSI_SYM53C8XX_IOMAPPED
bool "use port IO"
config SCSI_SYM53C8XX_MMIO
bool "Use memory mapped IO"
depends on SCSI_SYM53C8XX_2
default y
help
If you say Y here, the driver will use port IO to access
the card. This is significantly slower then using memory
mapped IO. Most people should answer N.
Memory mapped IO is faster than Port IO. Most people should
answer Y here, but some machines may have problems. If you have
to answer N here, please report the problem to the maintainer.
config SCSI_IPR
tristate "IBM Power Linux RAID adapter support"
@ -1309,15 +1310,6 @@ config SCSI_QLOGIC_FAS
To compile this driver as a module, choose M here: the
module will be called qlogicfas.
config SCSI_QLOGIC_FC
tristate "Qlogic ISP FC SCSI support"
depends on PCI && SCSI
help
This is a driver for the QLogic ISP2100 SCSI-FCP host adapter.
To compile this driver as a module, choose M here: the
module will be called qlogicfc.
config SCSI_QLOGIC_FC_FIRMWARE
bool "Include loadable firmware in driver"
depends on SCSI_QLOGIC_FC

View File

@ -78,7 +78,6 @@ obj-$(CONFIG_SCSI_NCR_Q720) += NCR_Q720_mod.o
obj-$(CONFIG_SCSI_SYM53C416) += sym53c416.o
obj-$(CONFIG_SCSI_QLOGIC_FAS) += qlogicfas408.o qlogicfas.o
obj-$(CONFIG_PCMCIA_QLOGIC) += qlogicfas408.o
obj-$(CONFIG_SCSI_QLOGIC_FC) += qlogicfc.o
obj-$(CONFIG_SCSI_QLOGIC_1280) += qla1280.o
obj-$(CONFIG_SCSI_QLA_FC) += qla2xxx/
obj-$(CONFIG_SCSI_LPFC) += lpfc/

View File

@ -149,20 +149,20 @@ static int dacmode = -1;
static int commit = -1;
module_param(nondasd, int, 0);
module_param(nondasd, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(nondasd, "Control scanning of hba for nondasd devices. 0=off, 1=on");
module_param(dacmode, int, 0);
module_param(dacmode, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(dacmode, "Control whether dma addressing is using 64 bit DAC. 0=off, 1=on");
module_param(commit, int, 0);
module_param(commit, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(commit, "Control whether a COMMIT_CONFIG is issued to the adapter for foreign arrays.\nThis is typically needed in systems that do not have a BIOS. 0=off, 1=on");
int numacb = -1;
module_param(numacb, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(numacb, "Request a limit to the number of adapter control blocks (FIB) allocated. Valid\nvalues are 512 and down. Default is to use suggestion from Firmware.");
MODULE_PARM_DESC(numacb, "Request a limit to the number of adapter control blocks (FIB) allocated. Valid values are 512 and down. Default is to use suggestion from Firmware.");
int acbsize = -1;
module_param(acbsize, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(acbsize, "Request a specific adapter control block (FIB) size. Valid values are 512,\n2048, 4096 and 8192. Default is to use suggestion from Firmware.");
MODULE_PARM_DESC(acbsize, "Request a specific adapter control block (FIB) size. Valid values are 512, 2048, 4096 and 8192. Default is to use suggestion from Firmware.");
/**
* aac_get_config_status - check the adapter configuration
* @common: adapter to query
@ -387,6 +387,7 @@ static void get_container_name_callback(void *context, struct fib * fibptr)
struct scsi_cmnd * scsicmd;
scsicmd = (struct scsi_cmnd *) context;
scsicmd->SCp.phase = AAC_OWNER_MIDLEVEL;
dprintk((KERN_DEBUG "get_container_name_callback[cpu %d]: t = %ld.\n", smp_processor_id(), jiffies));
if (fibptr == NULL)
@ -453,8 +454,10 @@ static int aac_get_container_name(struct scsi_cmnd * scsicmd, int cid)
/*
* Check that the command queued to the controller
*/
if (status == -EINPROGRESS)
if (status == -EINPROGRESS) {
scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;
return 0;
}
printk(KERN_WARNING "aac_get_container_name: aac_fib_send failed with status: %d.\n", status);
aac_fib_complete(cmd_fibcontext);
@ -907,9 +910,10 @@ static void io_callback(void *context, struct fib * fibptr)
u32 cid;
scsicmd = (struct scsi_cmnd *) context;
scsicmd->SCp.phase = AAC_OWNER_MIDLEVEL;
dev = (struct aac_dev *)scsicmd->device->host->hostdata;
cid = ID_LUN_TO_CONTAINER(scsicmd->device->id, scsicmd->device->lun);
cid = scmd_id(scsicmd);
if (nblank(dprintk(x))) {
u64 lba;
@ -1151,8 +1155,10 @@ static int aac_read(struct scsi_cmnd * scsicmd, int cid)
/*
* Check that the command queued to the controller
*/
if (status == -EINPROGRESS)
if (status == -EINPROGRESS) {
scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;
return 0;
}
printk(KERN_WARNING "aac_read: aac_fib_send failed with status: %d.\n", status);
/*
@ -1318,8 +1324,8 @@ static int aac_write(struct scsi_cmnd * scsicmd, int cid)
/*
* Check that the command queued to the controller
*/
if (status == -EINPROGRESS)
{
if (status == -EINPROGRESS) {
scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;
return 0;
}
@ -1341,6 +1347,7 @@ static void synchronize_callback(void *context, struct fib *fibptr)
struct scsi_cmnd *cmd;
cmd = context;
cmd->SCp.phase = AAC_OWNER_MIDLEVEL;
dprintk((KERN_DEBUG "synchronize_callback[cpu %d]: t = %ld.\n",
smp_processor_id(), jiffies));
@ -1354,7 +1361,7 @@ static void synchronize_callback(void *context, struct fib *fibptr)
else {
struct scsi_device *sdev = cmd->device;
struct aac_dev *dev = (struct aac_dev *)sdev->host->hostdata;
u32 cid = ID_LUN_TO_CONTAINER(sdev->id, sdev->lun);
u32 cid = sdev_id(sdev);
printk(KERN_WARNING
"synchronize_callback: synchronize failed, status = %d\n",
le32_to_cpu(synchronizereply->status));
@ -1386,12 +1393,12 @@ static int aac_synchronize(struct scsi_cmnd *scsicmd, int cid)
unsigned long flags;
/*
* Wait for all commands to complete to this specific
* target (block).
* Wait for all outstanding queued commands to complete to this
* specific target (block).
*/
spin_lock_irqsave(&sdev->list_lock, flags);
list_for_each_entry(cmd, &sdev->cmd_list, list)
if (cmd != scsicmd && cmd->serial_number != 0) {
if (cmd != scsicmd && cmd->SCp.phase == AAC_OWNER_FIRMWARE) {
++active;
break;
}
@ -1434,8 +1441,10 @@ static int aac_synchronize(struct scsi_cmnd *scsicmd, int cid)
/*
* Check that the command queued to the controller
*/
if (status == -EINPROGRESS)
if (status == -EINPROGRESS) {
scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;
return 0;
}
printk(KERN_WARNING
"aac_synchronize: aac_fib_send failed with status: %d.\n", status);
@ -1458,7 +1467,6 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
struct Scsi_Host *host = scsicmd->device->host;
struct aac_dev *dev = (struct aac_dev *)host->hostdata;
struct fsa_dev_info *fsa_dev_ptr = dev->fsa_dev;
int ret;
/*
* If the bus, id or lun is out of range, return fail
@ -1466,13 +1474,14 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
* itself.
*/
if (scmd_id(scsicmd) != host->this_id) {
if ((scsicmd->device->channel == CONTAINER_CHANNEL)) {
if( (scsicmd->device->id >= dev->maximum_num_containers) || (scsicmd->device->lun != 0)){
if ((scmd_channel(scsicmd) == CONTAINER_CHANNEL)) {
if((scmd_id(scsicmd) >= dev->maximum_num_containers) ||
(scsicmd->device->lun != 0)) {
scsicmd->result = DID_NO_CONNECT << 16;
scsicmd->scsi_done(scsicmd);
return 0;
}
cid = ID_LUN_TO_CONTAINER(scsicmd->device->id, scsicmd->device->lun);
cid = scmd_id(scsicmd);
/*
* If the target container doesn't exist, it may have
@ -1548,7 +1557,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
{
struct inquiry_data inq_data;
dprintk((KERN_DEBUG "INQUIRY command, ID: %d.\n", scsicmd->device->id));
dprintk((KERN_DEBUG "INQUIRY command, ID: %d.\n", scmd_id(scsicmd)));
memset(&inq_data, 0, sizeof (struct inquiry_data));
inq_data.inqd_ver = 2; /* claim compliance to SCSI-2 */
@ -1598,13 +1607,14 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
cp[11] = 0;
cp[12] = 0;
aac_internal_transfer(scsicmd, cp, 0,
min((unsigned int)scsicmd->cmnd[13], sizeof(cp)));
min_t(size_t, scsicmd->cmnd[13], sizeof(cp)));
if (sizeof(cp) < scsicmd->cmnd[13]) {
unsigned int len, offset = sizeof(cp);
memset(cp, 0, offset);
do {
len = min(scsicmd->cmnd[13]-offset, sizeof(cp));
len = min_t(size_t, scsicmd->cmnd[13] - offset,
sizeof(cp));
aac_internal_transfer(scsicmd, cp, offset, len);
} while ((offset += len) < scsicmd->cmnd[13]);
}
@ -1728,24 +1738,19 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
* containers to /dev/sd device names
*/
spin_unlock_irq(host->host_lock);
if (scsicmd->request->rq_disk)
strlcpy(fsa_dev_ptr[cid].devname,
scsicmd->request->rq_disk->disk_name,
min(sizeof(fsa_dev_ptr[cid].devname),
sizeof(scsicmd->request->rq_disk->disk_name) + 1));
ret = aac_read(scsicmd, cid);
spin_lock_irq(host->host_lock);
return ret;
return aac_read(scsicmd, cid);
case WRITE_6:
case WRITE_10:
case WRITE_12:
case WRITE_16:
spin_unlock_irq(host->host_lock);
ret = aac_write(scsicmd, cid);
spin_lock_irq(host->host_lock);
return ret;
return aac_write(scsicmd, cid);
case SYNCHRONIZE_CACHE:
/* Issue FIB to tell Firmware to flush it's cache */
@ -1778,7 +1783,7 @@ static int query_disk(struct aac_dev *dev, void __user *arg)
if (copy_from_user(&qd, arg, sizeof (struct aac_query_disk)))
return -EFAULT;
if (qd.cnum == -1)
qd.cnum = ID_LUN_TO_CONTAINER(qd.id, qd.lun);
qd.cnum = qd.id;
else if ((qd.bus == -1) && (qd.id == -1) && (qd.lun == -1))
{
if (qd.cnum < 0 || qd.cnum >= dev->maximum_num_containers)
@ -1890,6 +1895,7 @@ static void aac_srb_callback(void *context, struct fib * fibptr)
struct scsi_cmnd *scsicmd;
scsicmd = (struct scsi_cmnd *) context;
scsicmd->SCp.phase = AAC_OWNER_MIDLEVEL;
dev = (struct aac_dev *)scsicmd->device->host->hostdata;
if (fibptr == NULL)
@ -2068,14 +2074,13 @@ static int aac_send_srb_fib(struct scsi_cmnd* scsicmd)
u32 timeout;
dev = (struct aac_dev *)scsicmd->device->host->hostdata;
if (scsicmd->device->id >= dev->maximum_num_physicals ||
if (scmd_id(scsicmd) >= dev->maximum_num_physicals ||
scsicmd->device->lun > 7) {
scsicmd->result = DID_NO_CONNECT << 16;
scsicmd->scsi_done(scsicmd);
return 0;
}
dev = (struct aac_dev *)scsicmd->device->host->hostdata;
switch(scsicmd->sc_data_direction){
case DMA_TO_DEVICE:
flag = SRB_DataOut;
@ -2103,8 +2108,8 @@ static int aac_send_srb_fib(struct scsi_cmnd* scsicmd)
srbcmd = (struct aac_srb*) fib_data(cmd_fibcontext);
srbcmd->function = cpu_to_le32(SRBF_ExecuteScsi);
srbcmd->channel = cpu_to_le32(aac_logical_to_phys(scsicmd->device->channel));
srbcmd->id = cpu_to_le32(scsicmd->device->id);
srbcmd->channel = cpu_to_le32(aac_logical_to_phys(scmd_channel(scsicmd)));
srbcmd->id = cpu_to_le32(scmd_id(scsicmd));
srbcmd->lun = cpu_to_le32(scsicmd->device->lun);
srbcmd->flags = cpu_to_le32(flag);
timeout = scsicmd->timeout_per_command/HZ;
@ -2161,7 +2166,8 @@ static int aac_send_srb_fib(struct scsi_cmnd* scsicmd)
/*
* Check that the command queued to the controller
*/
if (status == -EINPROGRESS){
if (status == -EINPROGRESS) {
scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;
return 0;
}
@ -2192,8 +2198,6 @@ static unsigned long aac_build_sg(struct scsi_cmnd* scsicmd, struct sgmap* psg)
scsicmd->sc_data_direction);
psg->count = cpu_to_le32(sg_count);
byte_count = 0;
for (i = 0; i < sg_count; i++) {
psg->sg[i].addr = cpu_to_le32(sg_dma_address(sg));
psg->sg[i].count = cpu_to_le32(sg_dma_len(sg));
@ -2249,18 +2253,17 @@ static unsigned long aac_build_sg64(struct scsi_cmnd* scsicmd, struct sgmap64* p
sg_count = pci_map_sg(dev->pdev, sg, scsicmd->use_sg,
scsicmd->sc_data_direction);
psg->count = cpu_to_le32(sg_count);
byte_count = 0;
for (i = 0; i < sg_count; i++) {
int count = sg_dma_len(sg);
addr = sg_dma_address(sg);
psg->sg[i].addr[0] = cpu_to_le32(addr & 0xffffffff);
psg->sg[i].addr[1] = cpu_to_le32(addr>>32);
psg->sg[i].count = cpu_to_le32(sg_dma_len(sg));
byte_count += sg_dma_len(sg);
psg->sg[i].count = cpu_to_le32(count);
byte_count += count;
sg++;
}
psg->count = cpu_to_le32(sg_count);
/* hba wants the size to be exact */
if(byte_count > scsicmd->request_bufflen){
u32 temp = le32_to_cpu(psg->sg[i-1].count) -
@ -2275,16 +2278,15 @@ static unsigned long aac_build_sg64(struct scsi_cmnd* scsicmd, struct sgmap64* p
}
}
else if(scsicmd->request_bufflen) {
u64 addr;
addr = pci_map_single(dev->pdev,
scsicmd->SCp.dma_handle = pci_map_single(dev->pdev,
scsicmd->request_buffer,
scsicmd->request_bufflen,
scsicmd->sc_data_direction);
addr = scsicmd->SCp.dma_handle;
psg->count = cpu_to_le32(1);
psg->sg[0].addr[0] = cpu_to_le32(addr & 0xffffffff);
psg->sg[0].addr[1] = cpu_to_le32(addr >> 32);
psg->sg[0].count = cpu_to_le32(scsicmd->request_bufflen);
scsicmd->SCp.dma_handle = addr;
byte_count = scsicmd->request_bufflen;
}
return byte_count;

Some files were not shown because too many files have changed in this diff Show More