Commit 87746b70 authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://linux-scsi.bkbits.net/scsi-for-linus-2.5

into home.osdl.org:/home/torvalds/v2.5/linux
parents 47baacef e71fcd54
This diff is collapsed.
...@@ -133,7 +133,6 @@ ...@@ -133,7 +133,6 @@
#include <asm/byteorder.h> #include <asm/byteorder.h>
#include <linux/blk.h> #include <linux/blk.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/pci.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include "scsi.h" #include "scsi.h"
...@@ -564,8 +563,7 @@ NCR_700_unmap(struct NCR_700_Host_Parameters *hostdata, Scsi_Cmnd *SCp, ...@@ -564,8 +563,7 @@ NCR_700_unmap(struct NCR_700_Host_Parameters *hostdata, Scsi_Cmnd *SCp,
{ {
if(SCp->sc_data_direction != SCSI_DATA_NONE && if(SCp->sc_data_direction != SCSI_DATA_NONE &&
SCp->sc_data_direction != SCSI_DATA_UNKNOWN) { SCp->sc_data_direction != SCSI_DATA_UNKNOWN) {
enum dma_data_direction direction = enum dma_data_direction direction = SCp->sc_data_direction;
(enum dma_data_direction)scsi_to_pci_dma_dir(SCp->sc_data_direction);
if(SCp->use_sg) { if(SCp->use_sg) {
dma_unmap_sg(hostdata->dev, SCp->buffer, dma_unmap_sg(hostdata->dev, SCp->buffer,
SCp->use_sg, direction); SCp->use_sg, direction);
...@@ -1842,7 +1840,7 @@ NCR_700_queuecommand(Scsi_Cmnd *SCp, void (*done)(Scsi_Cmnd *)) ...@@ -1842,7 +1840,7 @@ NCR_700_queuecommand(Scsi_Cmnd *SCp, void (*done)(Scsi_Cmnd *))
} }
/* now build the scatter gather list */ /* now build the scatter gather list */
direction = (enum dma_data_direction)scsi_to_pci_dma_dir(SCp->sc_data_direction); direction = SCp->sc_data_direction;
if(move_ins != 0) { if(move_ins != 0) {
int i; int i;
int sg_count; int sg_count;
...@@ -2039,8 +2037,15 @@ NCR_700_init(void) ...@@ -2039,8 +2037,15 @@ NCR_700_init(void)
return 0; return 0;
} }
/* NULL exit routine to keep modutils happy */
STATIC void __exit
NCR_700_exit(void)
{
}
EXPORT_SYMBOL(NCR_700_detect); EXPORT_SYMBOL(NCR_700_detect);
EXPORT_SYMBOL(NCR_700_release); EXPORT_SYMBOL(NCR_700_release);
EXPORT_SYMBOL(NCR_700_intr); EXPORT_SYMBOL(NCR_700_intr);
module_init(NCR_700_init); module_init(NCR_700_init);
module_exit(NCR_700_exit);
...@@ -978,26 +978,16 @@ config SCSI_ZALON ...@@ -978,26 +978,16 @@ config SCSI_ZALON
used on the add-in Bluefish, Barracuda & Shrike SCSI cards. used on the add-in Bluefish, Barracuda & Shrike SCSI cards.
Say Y here if you have one of these machines or cards. Say Y here if you have one of these machines or cards.
config SCSI_NCR53C8XX config SCSI_NCR_Q720
tristate "NCR53C8XX SCSI support" tristate "NCR Quad 720 MCA SCSI support"
depends on PCI && SCSI_SYM53C8XX_2!=y && SCSI_ZALON!=y && SCSI depends on MCA && SCSI
---help--- help
This is the BSD ncr driver adapted to Linux for the NCR53C8XX family This is a driver for the MicroChannel Quad 720 card produced by
of PCI-SCSI controllers. This driver supports parity checking, NCR and commonly used in 345x/35xx/4100 class machines. It always
tagged command queuing and fast synchronous data transfers up to 80 tries to negotiate sync and uses tag command queueing.
MB/s with wide FAST-40 LVD devices and controllers.
Recent versions of the 53C8XX chips are better supported by the
option "SYM53C8XX SCSI support", below.
Note: there is yet another driver for the 53c8xx family of
controllers ("NCR53c7,8xx SCSI support" above). If you want to use
them both, you need to say M to both and build them as modules, but
only one may be active at a time. If you have a 53c8xx board, you
probably do not want to use the "NCR53c7,8xx SCSI support".
Please read <file:Documentation/scsi/ncr53c8xx.txt> for more Unless you have an NCR manufactured machine, the chances are that
information. you do not have this SCSI card, so say N.
config SCSI_SYM53C8XX config SCSI_SYM53C8XX
tristate "SYM53C8XX SCSI support" tristate "SYM53C8XX SCSI support"
...@@ -1027,8 +1017,8 @@ config SCSI_SYM53C8XX ...@@ -1027,8 +1017,8 @@ config SCSI_SYM53C8XX
information. information.
config SCSI_NCR53C8XX_DEFAULT_TAGS config SCSI_NCR53C8XX_DEFAULT_TAGS
int "default tagged command queue depth" int " default tagged command queue depth"
depends on PCI && SCSI_SYM53C8XX_2!=y && (SCSI_NCR53C8XX || SCSI_SYM53C8XX || SCSI_ZALON) depends on (SCSI_SYM53C8XX || SCSI_ZALON || SCSI_NCR_Q720)
default "8" default "8"
---help--- ---help---
"Tagged command queuing" is a feature of SCSI-2 which improves "Tagged command queuing" is a feature of SCSI-2 which improves
...@@ -1053,8 +1043,8 @@ config SCSI_NCR53C8XX_DEFAULT_TAGS ...@@ -1053,8 +1043,8 @@ config SCSI_NCR53C8XX_DEFAULT_TAGS
There is no safe option other than using good SCSI devices. There is no safe option other than using good SCSI devices.
config SCSI_NCR53C8XX_MAX_TAGS config SCSI_NCR53C8XX_MAX_TAGS
int "maximum number of queued commands" int " maximum number of queued commands"
depends on PCI && SCSI_SYM53C8XX_2!=y && (SCSI_NCR53C8XX || SCSI_SYM53C8XX || SCSI_ZALON) depends on (SCSI_SYM53C8XX || SCSI_ZALON || SCSI_NCR_Q720)
default "32" default "32"
---help--- ---help---
This option allows you to specify the maximum number of commands This option allows you to specify the maximum number of commands
...@@ -1070,8 +1060,8 @@ config SCSI_NCR53C8XX_MAX_TAGS ...@@ -1070,8 +1060,8 @@ config SCSI_NCR53C8XX_MAX_TAGS
There is no safe option and the default answer is recommended. There is no safe option and the default answer is recommended.
config SCSI_NCR53C8XX_SYNC config SCSI_NCR53C8XX_SYNC
int "synchronous transfers frequency in MHz" int " synchronous transfers frequency in MHz"
depends on PCI && SCSI_SYM53C8XX_2!=y && (SCSI_NCR53C8XX || SCSI_SYM53C8XX || SCSI_ZALON) depends on (SCSI_SYM53C8XX || SCSI_ZALON || SCSI_NCR_Q720)
default "20" default "20"
---help--- ---help---
The SCSI Parallel Interface-2 Standard defines 5 classes of transfer The SCSI Parallel Interface-2 Standard defines 5 classes of transfer
...@@ -1104,8 +1094,8 @@ config SCSI_NCR53C8XX_SYNC ...@@ -1104,8 +1094,8 @@ config SCSI_NCR53C8XX_SYNC
terminations and SCSI conformant devices. terminations and SCSI conformant devices.
config SCSI_NCR53C8XX_PROFILE config SCSI_NCR53C8XX_PROFILE
bool "enable profiling" bool " enable profiling"
depends on PCI && SCSI_SYM53C8XX_2!=y && (SCSI_NCR53C8XX || SCSI_SYM53C8XX || SCSI_ZALON) depends on (SCSI_SYM53C8XX || SCSI_ZALON || SCSI_NCR_Q720)
help help
This option allows you to enable profiling information gathering. This option allows you to enable profiling information gathering.
These statistics are not very accurate due to the low frequency These statistics are not very accurate due to the low frequency
...@@ -1115,8 +1105,8 @@ config SCSI_NCR53C8XX_PROFILE ...@@ -1115,8 +1105,8 @@ config SCSI_NCR53C8XX_PROFILE
The normal answer therefore is N. The normal answer therefore is N.
config SCSI_NCR53C8XX_IOMAPPED config SCSI_NCR53C8XX_IOMAPPED
bool "use normal IO" bool " use normal IO"
depends on PCI && SCSI_SYM53C8XX_2!=y && (SCSI_NCR53C8XX || SCSI_SYM53C8XX) && !SCSI_ZALON depends on SCSI_SYM53C8XX && !(SCSI_ZALON || SCSI_NCR_Q720)
help help
If you say Y here, the driver will use normal IO, as opposed to If you say Y here, the driver will use normal IO, as opposed to
memory mapped IO. Memory mapped IO has less latency than normal IO memory mapped IO. Memory mapped IO has less latency than normal IO
...@@ -1128,8 +1118,8 @@ config SCSI_NCR53C8XX_IOMAPPED ...@@ -1128,8 +1118,8 @@ config SCSI_NCR53C8XX_IOMAPPED
related problems. related problems.
config SCSI_NCR53C8XX_PQS_PDS config SCSI_NCR53C8XX_PQS_PDS
bool "include support for the NCR PQS/PDS SCSI card" bool " include support for the NCR PQS/PDS SCSI card"
depends on (SCSI_NCR53C8XX || SCSI_SYM53C8XX) && SCSI_SYM53C8XX depends on SCSI_SYM53C8XX
help help
Say Y here if you have a special SCSI adapter produced by NCR Say Y here if you have a special SCSI adapter produced by NCR
corporation called a PCI Quad SCSI or PCI Dual SCSI. You do not need corporation called a PCI Quad SCSI or PCI Dual SCSI. You do not need
...@@ -1140,8 +1130,8 @@ config SCSI_NCR53C8XX_PQS_PDS ...@@ -1140,8 +1130,8 @@ config SCSI_NCR53C8XX_PQS_PDS
The common answer here is N, but answering Y is safe. The common answer here is N, but answering Y is safe.
config SCSI_NCR53C8XX_NO_DISCONNECT config SCSI_NCR53C8XX_NO_DISCONNECT
bool "not allow targets to disconnect" bool " not allow targets to disconnect"
depends on PCI && SCSI_SYM53C8XX_2!=y && (SCSI_NCR53C8XX || SCSI_SYM53C8XX || SCSI_ZALON) && SCSI_NCR53C8XX_DEFAULT_TAGS=0 depends on (SCSI_SYM53C8XX || SCSI_ZALON || SCSI_NCR_Q720) && SCSI_NCR53C8XX_DEFAULT_TAGS=0
help help
This option is only provided for safety if you suspect some SCSI This option is only provided for safety if you suspect some SCSI
device of yours to not support properly the target-disconnect device of yours to not support properly the target-disconnect
...@@ -1150,8 +1140,8 @@ config SCSI_NCR53C8XX_NO_DISCONNECT ...@@ -1150,8 +1140,8 @@ config SCSI_NCR53C8XX_NO_DISCONNECT
than 1 device on a SCSI bus. The normal answer therefore is N. than 1 device on a SCSI bus. The normal answer therefore is N.
config SCSI_NCR53C8XX_SYMBIOS_COMPAT config SCSI_NCR53C8XX_SYMBIOS_COMPAT
bool "assume boards are SYMBIOS compatible (EXPERIMENTAL)" bool " assume boards are SYMBIOS compatible (EXPERIMENTAL)"
depends on PCI && SCSI_SYM53C8XX_2!=y && (SCSI_NCR53C8XX || SCSI_SYM53C8XX || SCSI_ZALON) && EXPERIMENTAL depends on (SCSI_SYM53C8XX || SCSI_ZALON || SCSI_NCR_Q720 ) && EXPERIMENTAL
---help--- ---help---
This option allows you to enable some features depending on GPIO This option allows you to enable some features depending on GPIO
wiring. These General Purpose Input/Output pins can be used for wiring. These General Purpose Input/Output pins can be used for
......
...@@ -68,6 +68,7 @@ obj-$(CONFIG_SCSI_GENERIC_NCR5380) += g_NCR5380.o ...@@ -68,6 +68,7 @@ obj-$(CONFIG_SCSI_GENERIC_NCR5380) += g_NCR5380.o
obj-$(CONFIG_SCSI_GENERIC_NCR5380_MMIO) += g_NCR5380_mmio.o obj-$(CONFIG_SCSI_GENERIC_NCR5380_MMIO) += g_NCR5380_mmio.o
obj-$(CONFIG_SCSI_NCR53C406A) += NCR53c406a.o obj-$(CONFIG_SCSI_NCR53C406A) += NCR53c406a.o
obj-$(CONFIG_SCSI_NCR_D700) += NCR_D700.o 53c700.o obj-$(CONFIG_SCSI_NCR_D700) += NCR_D700.o 53c700.o
obj-$(CONFIG_SCSI_NCR_Q720) += NCR_Q720_mod.o
obj-$(CONFIG_SCSI_SYM53C416) += sym53c416.o obj-$(CONFIG_SCSI_SYM53C416) += sym53c416.o
obj-$(CONFIG_SCSI_QLOGIC_FAS) += qlogicfas.o obj-$(CONFIG_SCSI_QLOGIC_FAS) += qlogicfas.o
obj-$(CONFIG_SCSI_QLOGIC_ISP) += qlogicisp.o obj-$(CONFIG_SCSI_QLOGIC_ISP) += qlogicisp.o
...@@ -81,7 +82,6 @@ obj-$(CONFIG_SCSI_DMX3191D) += dmx3191d.o ...@@ -81,7 +82,6 @@ obj-$(CONFIG_SCSI_DMX3191D) += dmx3191d.o
obj-$(CONFIG_SCSI_DTC3280) += dtc.o obj-$(CONFIG_SCSI_DTC3280) += dtc.o
obj-$(CONFIG_SCSI_SYM53C8XX_2) += sym53c8xx_2/ obj-$(CONFIG_SCSI_SYM53C8XX_2) += sym53c8xx_2/
obj-$(CONFIG_SCSI_SYM53C8XX) += sym53c8xx.o obj-$(CONFIG_SCSI_SYM53C8XX) += sym53c8xx.o
obj-$(CONFIG_SCSI_NCR53C8XX) += ncr53c8xx.o
obj-$(CONFIG_SCSI_ZALON) += zalon7xx.o obj-$(CONFIG_SCSI_ZALON) += zalon7xx.o
obj-$(CONFIG_SCSI_EATA_PIO) += eata_pio.o obj-$(CONFIG_SCSI_EATA_PIO) += eata_pio.o
obj-$(CONFIG_SCSI_7000FASST) += wd7000.o obj-$(CONFIG_SCSI_7000FASST) += wd7000.o
...@@ -133,7 +133,17 @@ sd_mod-objs := sd.o ...@@ -133,7 +133,17 @@ sd_mod-objs := sd.o
sr_mod-objs := sr.o sr_ioctl.o sr_vendor.o sr_mod-objs := sr.o sr_ioctl.o sr_vendor.o
initio-objs := ini9100u.o i91uscsi.o initio-objs := ini9100u.o i91uscsi.o
a100u2w-objs := inia100.o i60uscsi.o a100u2w-objs := inia100.o i60uscsi.o
ncr53c8xx-flags-$(CONFIG_SCSI_ZALON) \
:= -DCONFIG_NCR53C8XX_PREFETCH \
-DCONFIG_SCSI_NCR53C8XX_NO_WORD_TRANSFERS \
-DCONFIG_SCSI_NCR53C8XX_NO_NVRAM \
-DSCSI_NCR_BIG_ENDIAN -DSIMULATED_INTFLY
ncr53c8xx-flags-$(CONFIG_SCSI_NCR_Q720) \
:= -DCONFIG_SCSI_NCR53C8XX_NO_NVRAM \
-DSIMULATED_INTFLY
CFLAGS_ncr53c8xx.o := $(ncr53c8xx-flags-y) $(ncr53c8xx-flags-m)
zalon7xx-objs := zalon.o ncr53c8xx.o zalon7xx-objs := zalon.o ncr53c8xx.o
NCR_Q720_mod-objs := NCR_Q720.o ncr53c8xx.o
cpqfc-objs := cpqfcTSinit.o cpqfcTScontrol.o cpqfcTSi2c.o \ cpqfc-objs := cpqfcTSinit.o cpqfcTScontrol.o cpqfcTSi2c.o \
cpqfcTSworker.o cpqfcTStrigger.o cpqfcTSworker.o cpqfcTStrigger.o
......
/* -*- mode: c; c-basic-offset: 8 -*- */
/* NCR Quad 720 MCA SCSI Driver
*
* Copyright (C) 2003 by James.Bottomley@HansenPartnership.com
*/
#include <linux/blkdev.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/mca.h>
#include <linux/types.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <asm/io.h>
#include "scsi.h"
#include "hosts.h"
#include "ncr53c8xx.h"
#include "NCR_Q720.h"
static ncr_chip q720_chip __initdata = {
.device_id = PSEUDO_720_ID,
.revision_id = 0x0f,
.name = "720",
.burst_max = 3,
.offset_max = 8,
.nr_divisor = 4,
.features = FE_WIDE | FE_DIFF | FE_VARCLK,
};
MODULE_AUTHOR("James Bottomley");
MODULE_DESCRIPTION("NCR Quad 720 SCSI Driver");
MODULE_LICENSE("GPL");
#define NCR_Q720_VERSION "0.9"
/* We needs this helper because we have up to four hosts per struct device */
struct NCR_Q720_private {
struct device *dev;
__u32 mem_base;
__u32 phys_mem_base;
__u32 mem_size;
__u8 irq;
__u8 siops;
__u8 irq_enable;
struct Scsi_Host *hosts[4];
};
Scsi_Host_Template NCR_Q720_tpnt = {
.module = THIS_MODULE,
.proc_name = "NCR_Q720",
};
static irqreturn_t
NCR_Q720_intr(int irq, void *data, struct pt_regs * regs)
{
struct NCR_Q720_private *p = (struct NCR_Q720_private *)data;
__u8 sir = (readb(p->mem_base + 0x0d) & 0xf0) >> 4;
__u8 siop;
sir |= ~p->irq_enable;
if(sir == 0xff)
return IRQ_NONE;
while((siop = ffz(sir)) < p->siops) {
sir |= 1<<siop;
ncr53c8xx_intr(irq, p->hosts[siop], regs);
}
return IRQ_HANDLED;
}
static int __init
NCR_Q720_probe_one(struct NCR_Q720_private *p, int siop,
int irq, int slot, __u32 paddr, __u32 vaddr)
{
ncr_device device;
__u8 scsi_id;
static int unit = 0;
__u8 scsr1 = readb(vaddr + NCR_Q720_SCSR_OFFSET + 1);
__u8 differential = readb(vaddr + NCR_Q720_SCSR_OFFSET) & 0x20;
__u8 version;
scsi_id = scsr1 >> 4;
/* enable burst length 16 (FIXME: should allow this) */
scsr1 |= 0x02;
/* force a siop reset */
scsr1 |= 0x04;
writeb(scsr1, vaddr + NCR_Q720_SCSR_OFFSET + 1);
udelay(10);
version = readb(vaddr + 0x18) >> 4;
memset(&device, 0, sizeof(ncr_device));
/* Initialise ncr_device structure with items required by ncr_attach. */
device.chip = q720_chip;
device.chip.revision_id = version;
device.host_id = scsi_id;
device.dev = p->dev;
device.slot.base = paddr;
device.slot.base_c = paddr;
device.slot.base_v = vaddr;
device.slot.irq = irq;
device.differential = differential ? 2 : 0;
printk("Q720 probe unit %d (siop%d) at 0x%lx, diff = %d, vers = %d\n", unit, siop,
(unsigned long)paddr, differential, version);
p->hosts[siop] = ncr_attach(&NCR_Q720_tpnt, unit++, &device);
if (!p->hosts[siop])
goto fail;
p->irq_enable |= (1<<siop);
scsr1 = readb(vaddr + NCR_Q720_SCSR_OFFSET + 1);
/* clear the disable interrupt bit */
scsr1 &= ~0x01;
writeb(scsr1, vaddr + NCR_Q720_SCSR_OFFSET + 1);
scsi_add_host(p->hosts[siop], p->dev);
return 0;
fail:
return -ENODEV;
}
/* Detect a Q720 card. Note, because of the setup --- the chips are
* essentially connectecd to the MCA bus independently, it is easier
* to set them up as two separate host adapters, rather than one
* adapter with two channels */
static int __init
NCR_Q720_probe(struct device *dev)
{
struct NCR_Q720_private *p;
static int banner = 1;
struct mca_device *mca_dev = to_mca_device(dev);
int slot = mca_dev->slot;
int found = 0;
int irq, i, siops;
__u8 pos2, pos4, asr2, asr9, asr10;
__u16 io_base;
__u32 base_addr, mem_size;
__u32 mem_base;
p = kmalloc(sizeof(*p), GFP_KERNEL);
if (!p)
return -ENOMEM;
memset(p, 0, sizeof(*p));
pos2 = mca_device_read_pos(mca_dev, 2);
/* enable device */
pos2 |= NCR_Q720_POS2_BOARD_ENABLE | NCR_Q720_POS2_INTERRUPT_ENABLE;
mca_device_write_pos(mca_dev, 2, pos2);
io_base = (pos2 & NCR_Q720_POS2_IO_MASK) << NCR_Q720_POS2_IO_SHIFT;
if(banner) {
printk(KERN_NOTICE "NCR Q720: Driver Version " NCR_Q720_VERSION "\n"
"NCR Q720: Copyright (c) 2003 by James.Bottomley@HansenPartnership.com\n"
"NCR Q720:\n");
banner = 0;
}
io_base = mca_device_transform_ioport(mca_dev, io_base);
/* OK, this is phase one of the bootstrap, we now know the
* I/O space base address. All the configuration registers
* are mapped here (including pos) */
/* sanity check I/O mapping */
i = inb(io_base) | (inb(io_base+1)<<8);
if(i != NCR_Q720_MCA_ID) {
printk(KERN_ERR "NCR_Q720, adapter failed to I/O map registers correctly at 0x%x(0x%x)\n", io_base, i);
return -ENODEV;
}
/* Phase II, find the ram base and memory map the board register */
pos4 = inb(io_base + 4);
/* enable streaming data */
pos4 |= 0x01;
outb(pos4, io_base + 4);
base_addr = (pos4 & 0x7e) << 20;
base_addr += (pos4 & 0x80) << 23;
asr10 = inb(io_base + 0x12);
base_addr += (asr10 & 0x80) << 24;
base_addr += (asr10 & 0x70) << 23;
/* OK, got the base addr, now we need to find the ram size,
* enable and map it */
asr9 = inb(io_base + 0x11);
i = (asr9 & 0xc0) >> 6;
if(i == 0)
mem_size = 1024;
else
mem_size = 1 << (19 + i);
/* enable the sram mapping */
asr9 |= 0x20;
/* disable the rom mapping */
asr9 &= ~0x10;
outb(asr9, io_base + 0x11);
if(!request_mem_region(base_addr, mem_size, "NCR_Q720")) {
printk(KERN_ERR "NCR_Q720: Failed to claim memory region 0x%lx\n-0x%lx",
(unsigned long)base_addr,
(unsigned long)(base_addr + mem_size));
goto out_free;
}
mem_base = (__u32)ioremap(base_addr, mem_size);
/* now also enable accesses in asr 2 */
asr2 = inb(io_base + 0x0a);
asr2 |= 0x01;
outb(asr2, io_base + 0x0a);
/* get the number of SIOPs (this should be 2 or 4) */
siops = ((asr2 & 0xe0) >> 5) + 1;
/* sanity check mapping (again) */
i = readw(mem_base);
if(i != NCR_Q720_MCA_ID) {
printk(KERN_ERR "NCR_Q720, adapter failed to memory map registers correctly at 0x%lx(0x%x)\n", (unsigned long)base_addr, i);
goto out_release;
}
irq = readb(mem_base + 5) & 0x0f;
/* now do the bus related transforms */
irq = mca_device_transform_irq(mca_dev, irq);
printk(KERN_NOTICE "NCR Q720: found in slot %d irq = %d mem base = 0x%lx siops = %d\n", slot, irq, (unsigned long)base_addr, siops);
printk(KERN_NOTICE "NCR Q720: On board ram %dk\n", mem_size/1024);
p->dev = dev;
p->mem_base = mem_base;
p->phys_mem_base = base_addr;
p->mem_size = mem_size;
p->irq = irq;
p->siops = siops;
if (request_irq(irq, NCR_Q720_intr, SA_SHIRQ, "NCR_Q720", p)) {
printk(KERN_ERR "NCR_Q720: request irq %d failed\n", irq);
goto out_release;
}
/* disable all the siop interrupts */
for(i = 0; i < siops; i++) {
__u32 reg_scsr1 = mem_base + NCR_Q720_CHIP_REGISTER_OFFSET
+ i*NCR_Q720_SIOP_SHIFT + NCR_Q720_SCSR_OFFSET + 1;
__u8 scsr1 = readb(reg_scsr1);
scsr1 |= 0x01;
writeb(scsr1, reg_scsr1);
}
/* plumb in all 720 chips */
for (i = 0; i < siops; i++) {
__u32 siop_v_base = mem_base + NCR_Q720_CHIP_REGISTER_OFFSET
+ i*NCR_Q720_SIOP_SHIFT;
__u32 siop_p_base = base_addr + NCR_Q720_CHIP_REGISTER_OFFSET
+ i*NCR_Q720_SIOP_SHIFT;
__u16 port = io_base + NCR_Q720_CHIP_REGISTER_OFFSET
+ i*NCR_Q720_SIOP_SHIFT;
int err;
outb(0xff, port + 0x40);
outb(0x07, port + 0x41);
if ((err = NCR_Q720_probe_one(p, i, irq, slot,
siop_p_base, siop_v_base)) != 0)
printk("Q720: SIOP%d: probe failed, error = %d\n",
i, err);
else
found++;
}
if (!found) {
kfree(p);
return -ENODEV;
}
mca_device_set_claim(mca_dev, 1);
strlcpy(dev->name, "NCR_Q720", sizeof(dev->name));
dev_set_drvdata(dev, p);
return 0;
out_release:
iounmap((void *)mem_base);
release_mem_region(base_addr, mem_size);
out_free:
kfree(p);
return -ENODEV;
}
static void __exit
NCR_Q720_remove_one(struct Scsi_Host *host)
{
scsi_remove_host(host);
ncr53c8xx_release(host);
}
static int __exit
NCR_Q720_remove(struct device *dev)
{
struct NCR_Q720_private *p = dev_get_drvdata(dev);
int i;
for (i = 0; i < p->siops; i++)
if(p->hosts[i])
NCR_Q720_remove_one(p->hosts[i]);
iounmap((void *)p->mem_base);
release_mem_region(p->phys_mem_base, p->mem_size);
free_irq(p->irq, p);
kfree(p);
return 0;
}
static short NCR_Q720_id_table[] = { NCR_Q720_MCA_ID, 0 };
struct mca_driver NCR_Q720_driver = {
.id_table = NCR_Q720_id_table,
.driver = {
.name = "NCR_Q720",
.bus = &mca_bus_type,
.probe = NCR_Q720_probe,
.remove = __devexit_p(NCR_Q720_remove),
},
};
static int __init
NCR_Q720_init(void)
{
return mca_register_driver(&NCR_Q720_driver);
}
static void __exit
NCR_Q720_exit(void)
{
mca_unregister_driver(&NCR_Q720_driver);
//scsi_sysfs_release_attributes(&NCR_Q720_driver_template);
}
module_init(NCR_Q720_init);
module_exit(NCR_Q720_exit);
/* -*- mode: c; c-basic-offset: 8 -*- */
/* NCR Quad 720 MCA SCSI Driver
*
* Copyright (C) 2003 by James.Bottomley@HansenPartnership.com
*/
#ifndef _NCR_Q720_H
#define _NCR_Q720_H
/* The MCA identifier */
#define NCR_Q720_MCA_ID 0x0720
#define NCR_Q720_CLOCK_MHZ 30
#define NCR_Q720_POS2_BOARD_ENABLE 0x01
#define NCR_Q720_POS2_INTERRUPT_ENABLE 0x02
#define NCR_Q720_POS2_PARITY_DISABLE 0x04
#define NCR_Q720_POS2_IO_MASK 0xf8
#define NCR_Q720_POS2_IO_SHIFT 8
#define NCR_Q720_CHIP_REGISTER_OFFSET 0x200
#define NCR_Q720_SCSR_OFFSET 0x070
#define NCR_Q720_SIOP_SHIFT 0x080
#endif
This diff is collapsed.
This diff is collapsed.
...@@ -12,11 +12,6 @@ ...@@ -12,11 +12,6 @@
#include <linux/types.h> #include <linux/types.h>
/* Eisa Enhanced mode operation - slot locating and addressing */
#define MINEISA 1 /* I don't have an EISA Spec to know these ranges, so I */
#define MAXEISA 8 /* Just took my machine's specifications. Adjust to fit. */
/* I just saw an ad, and bumped this from 6 to 8 */
#define SLOTBASE(x) ((x << 12) + 0xc80)
#define SLOTSIZE 0x5c #define SLOTSIZE 0x5c
/* EISA configuration registers & values */ /* EISA configuration registers & values */
...@@ -152,11 +147,6 @@ struct ecb { /* Enhanced Control Block 6.1 */ ...@@ -152,11 +147,6 @@ struct ecb { /* Enhanced Control Block 6.1 */
#define AHA1740CMD_RINQ 0x0a /* Read Host Adapter Inquiry Data */ #define AHA1740CMD_RINQ 0x0a /* Read Host Adapter Inquiry Data */
#define AHA1740CMD_TARG 0x10 /* Target SCSI Command */ #define AHA1740CMD_TARG 0x10 /* Target SCSI Command */
static int aha1740_detect(Scsi_Host_Template *);
static int aha1740_command(Scsi_Cmnd *);
static int aha1740_queuecommand(Scsi_Cmnd *, void (*done) (Scsi_Cmnd *));
static int aha1740_biosparam(struct scsi_device *, struct block_device *, sector_t, int *);
#define AHA1740_ECBS 32 #define AHA1740_ECBS 32
#define AHA1740_SCATTER 16 #define AHA1740_SCATTER 16
#define AHA1740_CMDLUN 1 #define AHA1740_CMDLUN 1
......
...@@ -59,6 +59,7 @@ ...@@ -59,6 +59,7 @@
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/pci.h>
/*--------------------------------------------------------------------------- /*---------------------------------------------------------------------------
Features Features
......
...@@ -82,6 +82,13 @@ int scsi_add_host(struct Scsi_Host *shost, struct device *dev) ...@@ -82,6 +82,13 @@ int scsi_add_host(struct Scsi_Host *shost, struct device *dev)
sht->info ? sht->info(shost) : sht->name); sht->info ? sht->info(shost) : sht->name);
error = scsi_sysfs_add_host(shost, dev); error = scsi_sysfs_add_host(shost, dev);
if (!shost->can_queue) {
printk(KERN_ERR "%s: can_queue = 0 no longer supported\n",
sht->name);
error = -EINVAL;
}
if (!error) { if (!error) {
scsi_proc_host_add(shost); scsi_proc_host_add(shost);
scsi_scan_host(shost); scsi_scan_host(shost);
...@@ -187,7 +194,7 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize) ...@@ -187,7 +194,7 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)
shost->use_blk_tcq = sht->use_blk_tcq; shost->use_blk_tcq = sht->use_blk_tcq;
shost->highmem_io = sht->highmem_io; shost->highmem_io = sht->highmem_io;
if (!sht->max_host_blocked) if (sht->max_host_blocked)
shost->max_host_blocked = sht->max_host_blocked; shost->max_host_blocked = sht->max_host_blocked;
else else
shost->max_host_blocked = SCSI_DEFAULT_HOST_BLOCKED; shost->max_host_blocked = SCSI_DEFAULT_HOST_BLOCKED;
......
...@@ -26,29 +26,9 @@ ...@@ -26,29 +26,9 @@
#include <linux/config.h> #include <linux/config.h>
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#include <linux/types.h>
#include <scsi/scsi_host.h> #include <scsi/scsi_host.h>
struct scsi_driver {
struct module *owner;
struct device_driver gendrv;
int (*init_command)(struct scsi_cmnd *);
void (*rescan)(struct device *);
};
#define to_scsi_driver(drv) \
container_of((drv), struct scsi_driver, gendrv)
extern int scsi_register_driver(struct device_driver *);
#define scsi_unregister_driver(drv) \
driver_unregister(drv);
extern int scsi_register_interface(struct class_interface *);
#define scsi_unregister_interface(intf) \
class_interface_unregister(intf)
/** /**
* scsi_find_device - find a device given the host * scsi_find_device - find a device given the host
* @shost: SCSI host pointer * @shost: SCSI host pointer
......
...@@ -2379,7 +2379,6 @@ static int ibmmca_proc_info(struct Scsi_Host *shpnt, char *buffer, char **start, ...@@ -2379,7 +2379,6 @@ static int ibmmca_proc_info(struct Scsi_Host *shpnt, char *buffer, char **start,
{ {
int len = 0; int len = 0;
int i, id, lun, host_index; int i, id, lun, host_index;
struct Scsi_Host *shpnt;
unsigned long flags; unsigned long flags;
int max_pun; int max_pun;
...@@ -2452,11 +2451,6 @@ static int ibmmca_proc_info(struct Scsi_Host *shpnt, char *buffer, char **start, ...@@ -2452,11 +2451,6 @@ static int ibmmca_proc_info(struct Scsi_Host *shpnt, char *buffer, char **start,
return len; return len;
} }
static void ibmmca_scsi_setup(char *str, int *ints)
{
internal_ibmmca_scsi_setup(str, ints);
}
static int option_setup(char *str) static int option_setup(char *str)
{ {
int ints[IM_MAX_HOSTS]; int ints[IM_MAX_HOSTS];
......
...@@ -13,7 +13,6 @@ ...@@ -13,7 +13,6 @@
/* Interfaces to the midlevel Linux SCSI driver */ /* Interfaces to the midlevel Linux SCSI driver */
static int ibmmca_detect (Scsi_Host_Template *); static int ibmmca_detect (Scsi_Host_Template *);
static int ibmmca_release (struct Scsi_Host *); static int ibmmca_release (struct Scsi_Host *);
static int ibmmca_command (Scsi_Cmnd *);
static int ibmmca_queuecommand (Scsi_Cmnd *, void (*done) (Scsi_Cmnd *)); static int ibmmca_queuecommand (Scsi_Cmnd *, void (*done) (Scsi_Cmnd *));
static int ibmmca_abort (Scsi_Cmnd *); static int ibmmca_abort (Scsi_Cmnd *);
static int ibmmca_host_reset (Scsi_Cmnd *); static int ibmmca_host_reset (Scsi_Cmnd *);
......
...@@ -7009,10 +7009,10 @@ static int ips_init_phase1( struct pci_dev *pci_dev, int *indexPtr ) ...@@ -7009,10 +7009,10 @@ static int ips_init_phase1( struct pci_dev *pci_dev, int *indexPtr )
* are guaranteed to be < 4G. * are guaranteed to be < 4G.
*/ */
if ( IPS_ENABLE_DMA64 && IPS_HAS_ENH_SGLIST(ha) && if ( IPS_ENABLE_DMA64 && IPS_HAS_ENH_SGLIST(ha) &&
!pci_set_dma_mask(ha->pcidev, (u64)0xffffffffffffffff)) { !pci_set_dma_mask(ha->pcidev, 0xffffffffffffffffULL)) {
(ha)->flags |= IPS_HA_ENH_SG; (ha)->flags |= IPS_HA_ENH_SG;
} else { } else {
if ( pci_set_dma_mask(ha->pcidev, (u64)0xffffffff) != 0 ) { if ( pci_set_dma_mask(ha->pcidev, 0xffffffffULL) != 0 ) {
printk(KERN_WARNING "Unable to set DMA Mask\n"); printk(KERN_WARNING "Unable to set DMA Mask\n");
return ips_abort_init(ha, index); return ips_abort_init(ha, index);
} }
......
...@@ -76,6 +76,7 @@ static struct parisc_driver lasi700_driver = { ...@@ -76,6 +76,7 @@ static struct parisc_driver lasi700_driver = {
.name = "Lasi SCSI", .name = "Lasi SCSI",
.id_table = lasi700_scsi_tbl, .id_table = lasi700_scsi_tbl,
.probe = lasi700_driver_callback, .probe = lasi700_driver_callback,
.remove = __devexit_p(lasi700_driver_remove),
}; };
static int __init static int __init
...@@ -97,12 +98,6 @@ lasi700_driver_callback(struct parisc_device *dev) ...@@ -97,12 +98,6 @@ lasi700_driver_callback(struct parisc_device *dev)
} }
memset(hostdata, 0, sizeof(struct NCR_700_Host_Parameters)); memset(hostdata, 0, sizeof(struct NCR_700_Host_Parameters));
if (!request_mem_region(base, 64, dev->dev.name)) {
printk(KERN_ERR "%s: Failed to claim memory region\n",
dev->dev.name);
goto out_kfree;
}
hostdata->dev = &dev->dev; hostdata->dev = &dev->dev;
dma_set_mask(&dev->dev, 0xffffffffUL); dma_set_mask(&dev->dev, 0xffffffffUL);
hostdata->base = base; hostdata->base = base;
...@@ -122,7 +117,7 @@ lasi700_driver_callback(struct parisc_device *dev) ...@@ -122,7 +117,7 @@ lasi700_driver_callback(struct parisc_device *dev)
host = NCR_700_detect(&lasi700_template, hostdata); host = NCR_700_detect(&lasi700_template, hostdata);
if (!host) if (!host)
goto out_release_mem_region; goto out_kfree;
host->irq = dev->irq; host->irq = dev->irq;
if (request_irq(dev->irq, NCR_700_intr, SA_SHIRQ, if (request_irq(dev->irq, NCR_700_intr, SA_SHIRQ,
...@@ -132,33 +127,33 @@ lasi700_driver_callback(struct parisc_device *dev) ...@@ -132,33 +127,33 @@ lasi700_driver_callback(struct parisc_device *dev)
goto out_put_host; goto out_put_host;
} }
dev_set_drvdata(&dev->dev, host);
scsi_add_host(host, &dev->dev); scsi_add_host(host, &dev->dev);
return 0; return 0;
out_put_host: out_put_host:
scsi_host_put(host); scsi_host_put(host);
out_release_mem_region:
release_mem_region(base, 64);
out_kfree: out_kfree:
kfree(hostdata); kfree(hostdata);
return 1; return -ENODEV;
} }
#if 0 static int __exit
static int lasi700_driver_remove(struct parisc_device *dev)
lasi700_release(struct Scsi_Host *host)
{ {
struct D700_Host_Parameters *hostdata = struct Scsi_Host *host = dev_get_drvdata(&dev->dev);
(struct D700_Host_Parameters *)host->hostdata[0]; struct NCR_700_Host_Parameters *hostdata =
(struct NCR_700_Host_Parameters *)host->hostdata[0];
scsi_remove_host(host);
NCR_700_release(host); NCR_700_release(host);
kfree(hostdata);
free_irq(host->irq, host); free_irq(host->irq, host);
release_mem_region(host->base, 64); kfree(hostdata);
unregister_parisc_driver(&lasi700_driver);
return 1; return 0;
} }
#endif
static int __init static int __init
lasi700_init(void) lasi700_init(void)
...@@ -166,4 +161,12 @@ lasi700_init(void) ...@@ -166,4 +161,12 @@ lasi700_init(void)
return register_parisc_driver(&lasi700_driver); return register_parisc_driver(&lasi700_driver);
} }
static void __exit
lasi700_exit(void)
{
unregister_parisc_driver(&lasi700_driver);
scsi_sysfs_release_attributes(&lasi700_template);
}
module_init(lasi700_init); module_init(lasi700_init);
module_exit(lasi700_exit);
...@@ -25,9 +25,8 @@ ...@@ -25,9 +25,8 @@
#ifndef _LASI700_H #ifndef _LASI700_H
#define _LASI700_H #define _LASI700_H
static int lasi700_detect(Scsi_Host_Template *);
static int lasi700_driver_callback(struct parisc_device *dev); static int lasi700_driver_callback(struct parisc_device *dev);
static int lasi700_release(struct Scsi_Host *host); static int lasi700_driver_remove(struct parisc_device *dev);
#define LASI_710_SVERSION 0x082 #define LASI_710_SVERSION 0x082
#define LASI_700_SVERSION 0x071 #define LASI_700_SVERSION 0x071
......
...@@ -40,6 +40,7 @@ ...@@ -40,6 +40,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/list.h> #include <linux/list.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/pci.h>
#include <scsi/scsicam.h> #include <scsi/scsicam.h>
#include "scsi.h" #include "scsi.h"
......
This diff is collapsed.
...@@ -42,6 +42,79 @@ ...@@ -42,6 +42,79 @@
#ifndef NCR53C8XX_H #ifndef NCR53C8XX_H
#define NCR53C8XX_H #define NCR53C8XX_H
/*
** Define the BSD style u_int32 and u_int64 type.
** Are in fact u_int32_t and u_int64_t :-)
*/
typedef u32 u_int32;
typedef u64 u_int64;
typedef u_long vm_offset_t;
#include "sym53c8xx_defs.h" #include "sym53c8xx_defs.h"
/*==========================================================
**
** Structures used by the detection routine to transmit
** device configuration to the attach function.
**
**==========================================================
*/
typedef struct {
int bus;
u_char device_fn;
u_long base;
u_long base_2;
u_long io_port;
u_long base_c;
u_long base_2_c;
u_long base_v;
u_long base_2_v;
int irq;
/* port and reg fields to use INB, OUTB macros */
u_long base_io;
volatile struct ncr_reg *reg;
} ncr_slot;
/*==========================================================
**
** Structure used to store the NVRAM content.
**
**==========================================================
*/
typedef struct {
int type;
#define SCSI_NCR_SYMBIOS_NVRAM (1)
#define SCSI_NCR_TEKRAM_NVRAM (2)
#ifdef SCSI_NCR_NVRAM_SUPPORT
union {
Symbios_nvram Symbios;
Tekram_nvram Tekram;
} data;
#endif
} ncr_nvram;
/*==========================================================
**
** Structure used by detection routine to save data on
** each detected board for attach.
**
**==========================================================
*/
typedef struct {
struct device *dev;
ncr_slot slot;
ncr_chip chip;
ncr_nvram *nvram;
u_char host_id;
#ifdef SCSI_NCR_PQS_PDS_SUPPORT
u_char pqs_pds;
#endif
__u8 differential;
int attach_done;
} ncr_device;
extern struct Scsi_Host *ncr_attach (Scsi_Host_Template *tpnt, int unit, ncr_device *device);
extern int ncr53c8xx_release(struct Scsi_Host *host);
irqreturn_t ncr53c8xx_intr(int irq, void *dev_id, struct pt_regs * regs);
#endif /* NCR53C8XX_H */ #endif /* NCR53C8XX_H */
...@@ -283,7 +283,6 @@ static const char *nsp32_info(struct Scsi_Host *); ...@@ -283,7 +283,6 @@ static const char *nsp32_info(struct Scsi_Host *);
static int nsp32_eh_abort(Scsi_Cmnd *); static int nsp32_eh_abort(Scsi_Cmnd *);
static int nsp32_eh_bus_reset(Scsi_Cmnd *); static int nsp32_eh_bus_reset(Scsi_Cmnd *);
static int nsp32_eh_host_reset(Scsi_Cmnd *); static int nsp32_eh_host_reset(Scsi_Cmnd *);
static int nsp32_reset(Scsi_Cmnd *, unsigned int);
static int nsp32_proc_info(struct Scsi_Host *, char *, char **, off_t, int, int); static int nsp32_proc_info(struct Scsi_Host *, char *, char **, off_t, int, int);
static int __devinit nsp32_probe(struct pci_dev *, const struct pci_device_id *); static int __devinit nsp32_probe(struct pci_dev *, const struct pci_device_id *);
static void __devexit nsp32_remove(struct pci_dev *); static void __devexit nsp32_remove(struct pci_dev *);
...@@ -1854,18 +1853,6 @@ static const char *nsp32_info(struct Scsi_Host *shpnt) ...@@ -1854,18 +1853,6 @@ static const char *nsp32_info(struct Scsi_Host *shpnt)
} }
/*
* error handler
*/
static int nsp32_reset(Scsi_Cmnd *SCpnt, unsigned int reset_flags)
{
nsp32_dbg(NSP32_DEBUG_BUSRESET, "SCpnt=0x%p why=%d\n", SCpnt, reset_flags);
nsp32_eh_bus_reset(SCpnt);
return SCSI_RESET_SUCCESS | SCSI_RESET_BUS_RESET;
}
static int nsp32_eh_abort(Scsi_Cmnd *SCpnt) static int nsp32_eh_abort(Scsi_Cmnd *SCpnt)
{ {
nsp32_hw_data *data = (nsp32_hw_data *)SCpnt->device->host->hostdata; nsp32_hw_data *data = (nsp32_hw_data *)SCpnt->device->host->hostdata;
......
...@@ -63,6 +63,7 @@ const char * osst_version = "0.99.0"; ...@@ -63,6 +63,7 @@ const char * osst_version = "0.99.0";
#include "scsi.h" #include "scsi.h"
#include "hosts.h" #include "hosts.h"
#include <scsi/scsi_driver.h>
#include <scsi/scsi_ioctl.h> #include <scsi/scsi_ioctl.h>
#define ST_KILOBYTE 1024 #define ST_KILOBYTE 1024
......
...@@ -139,7 +139,7 @@ struct scsi_request *scsi_allocate_request(struct scsi_device *sdev) ...@@ -139,7 +139,7 @@ struct scsi_request *scsi_allocate_request(struct scsi_device *sdev)
sreq->sr_device = sdev; sreq->sr_device = sdev;
sreq->sr_host = sdev->host; sreq->sr_host = sdev->host;
sreq->sr_magic = SCSI_REQ_MAGIC; sreq->sr_magic = SCSI_REQ_MAGIC;
sreq->sr_data_direction = SCSI_DATA_UNKNOWN; sreq->sr_data_direction = DMA_BIDIRECTIONAL;
} }
return sreq; return sreq;
......
...@@ -24,54 +24,6 @@ ...@@ -24,54 +24,6 @@
#include <scsi/scsi_tcq.h> #include <scsi/scsi_tcq.h>
#include <scsi/scsi.h> #include <scsi/scsi.h>
/*
* These are the values that the SCpnt->sc_data_direction and
* SRpnt->sr_data_direction can take. These need to be set
* The SCSI_DATA_UNKNOWN value is essentially the default.
* In the event that the command creator didn't bother to
* set a value, you will see SCSI_DATA_UNKNOWN.
*/
#define SCSI_DATA_UNKNOWN 0
#define SCSI_DATA_WRITE 1
#define SCSI_DATA_READ 2
#define SCSI_DATA_NONE 3
#ifdef CONFIG_PCI
#include <linux/pci.h>
#if ((SCSI_DATA_UNKNOWN == PCI_DMA_BIDIRECTIONAL) && (SCSI_DATA_WRITE == PCI_DMA_TODEVICE) && (SCSI_DATA_READ == PCI_DMA_FROMDEVICE) && (SCSI_DATA_NONE == PCI_DMA_NONE))
#define scsi_to_pci_dma_dir(scsi_dir) ((int)(scsi_dir))
#else
extern __inline__ int scsi_to_pci_dma_dir(unsigned char scsi_dir)
{
if (scsi_dir == SCSI_DATA_UNKNOWN)
return PCI_DMA_BIDIRECTIONAL;
if (scsi_dir == SCSI_DATA_WRITE)
return PCI_DMA_TODEVICE;
if (scsi_dir == SCSI_DATA_READ)
return PCI_DMA_FROMDEVICE;
return PCI_DMA_NONE;
}
#endif
#endif
#if defined(CONFIG_SBUS) && !defined(CONFIG_SUN3) && !defined(CONFIG_SUN3X)
#include <asm/sbus.h>
#if ((SCSI_DATA_UNKNOWN == SBUS_DMA_BIDIRECTIONAL) && (SCSI_DATA_WRITE == SBUS_DMA_TODEVICE) && (SCSI_DATA_READ == SBUS_DMA_FROMDEVICE) && (SCSI_DATA_NONE == SBUS_DMA_NONE))
#define scsi_to_sbus_dma_dir(scsi_dir) ((int)(scsi_dir))
#else
extern __inline__ int scsi_to_sbus_dma_dir(unsigned char scsi_dir)
{
if (scsi_dir == SCSI_DATA_UNKNOWN)
return SBUS_DMA_BIDIRECTIONAL;
if (scsi_dir == SCSI_DATA_WRITE)
return SBUS_DMA_TODEVICE;
if (scsi_dir == SCSI_DATA_READ)
return SBUS_DMA_FROMDEVICE;
return SBUS_DMA_NONE;
}
#endif
#endif
/* /*
* Some defs, in case these are not defined elsewhere. * Some defs, in case these are not defined elsewhere.
*/ */
...@@ -227,6 +179,21 @@ extern int scsi_sysfs_modify_sdev_attribute(struct device_attribute ***dev_attrs ...@@ -227,6 +179,21 @@ extern int scsi_sysfs_modify_sdev_attribute(struct device_attribute ***dev_attrs
extern int scsi_sysfs_modify_shost_attribute(struct class_device_attribute ***class_attrs, extern int scsi_sysfs_modify_shost_attribute(struct class_device_attribute ***class_attrs,
struct class_device_attribute *attr); struct class_device_attribute *attr);
/*
* Legacy dma direction interfaces.
*
* This assumes the pci/sbus dma mapping flags have the same numercial
* values as the generic dma-mapping ones. Currently they have but there's
* no way to check. Better don't use these interfaces!
*/
#define SCSI_DATA_UNKNOWN (DMA_BIDIRECTIONAL)
#define SCSI_DATA_WRITE (DMA_TO_DEVICE)
#define SCSI_DATA_READ (DMA_FROM_DEVICE)
#define SCSI_DATA_NONE (DMA_NONE)
#define scsi_to_pci_dma_dir(scsi_dir) ((int)(scsi_dir))
#define scsi_to_sbus_dma_dir(scsi_dir) ((int)(scsi_dir))
/* /*
* This is the crap from the old error handling code. We have it in a special * This is the crap from the old error handling code. We have it in a special
* place so that we can more easily delete it later on. * place so that we can more easily delete it later on.
......
...@@ -532,14 +532,14 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, int timeout) ...@@ -532,14 +532,14 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, int timeout)
static int scsi_request_sense(struct scsi_cmnd *scmd) static int scsi_request_sense(struct scsi_cmnd *scmd)
{ {
static unsigned char generic_sense[6] = static unsigned char generic_sense[6] =
{REQUEST_SENSE, 0, 0, 0, 254, 0}; {REQUEST_SENSE, 0, 0, 0, 252, 0};
unsigned char *scsi_result; unsigned char *scsi_result;
int saved_result; int saved_result;
int rtn; int rtn;
memcpy(scmd->cmnd, generic_sense, sizeof(generic_sense)); memcpy(scmd->cmnd, generic_sense, sizeof(generic_sense));
scsi_result = kmalloc(254, GFP_ATOMIC | (scmd->device->host->hostt->unchecked_isa_dma) ? __GFP_DMA : 0); scsi_result = kmalloc(252, GFP_ATOMIC | (scmd->device->host->hostt->unchecked_isa_dma) ? __GFP_DMA : 0);
if (unlikely(!scsi_result)) { if (unlikely(!scsi_result)) {
...@@ -555,14 +555,14 @@ static int scsi_request_sense(struct scsi_cmnd *scmd) ...@@ -555,14 +555,14 @@ static int scsi_request_sense(struct scsi_cmnd *scmd)
* address (db). 0 is not a valid sense code. * address (db). 0 is not a valid sense code.
*/ */
memset(scmd->sense_buffer, 0, sizeof(scmd->sense_buffer)); memset(scmd->sense_buffer, 0, sizeof(scmd->sense_buffer));
memset(scsi_result, 0, 254); memset(scsi_result, 0, 252);
saved_result = scmd->result; saved_result = scmd->result;
scmd->request_buffer = scsi_result; scmd->request_buffer = scsi_result;
scmd->request_bufflen = 254; scmd->request_bufflen = 252;
scmd->use_sg = 0; scmd->use_sg = 0;
scmd->cmd_len = COMMAND_SIZE(scmd->cmnd[0]); scmd->cmd_len = COMMAND_SIZE(scmd->cmnd[0]);
scmd->sc_data_direction = SCSI_DATA_READ; scmd->sc_data_direction = DMA_FROM_DEVICE;
scmd->underflow = 0; scmd->underflow = 0;
rtn = scsi_send_eh_cmnd(scmd, SENSE_TIMEOUT); rtn = scsi_send_eh_cmnd(scmd, SENSE_TIMEOUT);
...@@ -742,7 +742,7 @@ static int scsi_eh_tur(struct scsi_cmnd *scmd) ...@@ -742,7 +742,7 @@ static int scsi_eh_tur(struct scsi_cmnd *scmd)
scmd->use_sg = 0; scmd->use_sg = 0;
scmd->cmd_len = COMMAND_SIZE(scmd->cmnd[0]); scmd->cmd_len = COMMAND_SIZE(scmd->cmnd[0]);
scmd->underflow = 0; scmd->underflow = 0;
scmd->sc_data_direction = SCSI_DATA_NONE; scmd->sc_data_direction = DMA_NONE;
rtn = scsi_send_eh_cmnd(scmd, SENSE_TIMEOUT); rtn = scsi_send_eh_cmnd(scmd, SENSE_TIMEOUT);
...@@ -1338,7 +1338,7 @@ static void scsi_eh_lock_door(struct scsi_device *sdev) ...@@ -1338,7 +1338,7 @@ static void scsi_eh_lock_door(struct scsi_device *sdev)
if (unlikely(!sreq)) { if (unlikely(!sreq)) {
printk(KERN_ERR "%s: request allocate failed," printk(KERN_ERR "%s: request allocate failed,"
"prevent media removal cmd not sent", __FUNCTION__); "prevent media removal cmd not sent\n", __FUNCTION__);
return; return;
} }
...@@ -1348,7 +1348,7 @@ static void scsi_eh_lock_door(struct scsi_device *sdev) ...@@ -1348,7 +1348,7 @@ static void scsi_eh_lock_door(struct scsi_device *sdev)
sreq->sr_cmnd[3] = 0; sreq->sr_cmnd[3] = 0;
sreq->sr_cmnd[4] = SCSI_REMOVAL_PREVENT; sreq->sr_cmnd[4] = SCSI_REMOVAL_PREVENT;
sreq->sr_cmnd[5] = 0; sreq->sr_cmnd[5] = 0;
sreq->sr_data_direction = SCSI_DATA_NONE; sreq->sr_data_direction = DMA_NONE;
sreq->sr_bufflen = 0; sreq->sr_bufflen = 0;
sreq->sr_buffer = NULL; sreq->sr_buffer = NULL;
sreq->sr_allowed = 5; sreq->sr_allowed = 5;
...@@ -1723,7 +1723,7 @@ scsi_reset_provider(struct scsi_device *dev, int flag) ...@@ -1723,7 +1723,7 @@ scsi_reset_provider(struct scsi_device *dev, int flag)
scmd->cmd_len = 0; scmd->cmd_len = 0;
scmd->sc_data_direction = SCSI_DATA_UNKNOWN; scmd->sc_data_direction = DMA_BIDIRECTIONAL;
scmd->sc_request = NULL; scmd->sc_request = NULL;
scmd->sc_magic = SCSI_CMND_MAGIC; scmd->sc_magic = SCSI_CMND_MAGIC;
......
...@@ -104,7 +104,7 @@ static int ioctl_internal_command(struct scsi_device *sdev, char *cmd, ...@@ -104,7 +104,7 @@ static int ioctl_internal_command(struct scsi_device *sdev, char *cmd,
return -ENOMEM; return -ENOMEM;
} }
sreq->sr_data_direction = SCSI_DATA_NONE; sreq->sr_data_direction = DMA_NONE;
scsi_wait_req(sreq, cmd, NULL, 0, timeout, retries); scsi_wait_req(sreq, cmd, NULL, 0, timeout, retries);
SCSI_LOG_IOCTL(2, printk("Ioctl returned 0x%x\n", sreq->sr_result)); SCSI_LOG_IOCTL(2, printk("Ioctl returned 0x%x\n", sreq->sr_result));
...@@ -258,19 +258,19 @@ int scsi_ioctl_send_command(struct scsi_device *sdev, ...@@ -258,19 +258,19 @@ int scsi_ioctl_send_command(struct scsi_device *sdev,
return -ENOMEM; return -ENOMEM;
memset(buf, 0, buf_needed); memset(buf, 0, buf_needed);
if (inlen == 0) { if (inlen == 0) {
data_direction = SCSI_DATA_READ; data_direction = DMA_FROM_DEVICE;
} else if (outlen == 0 ) { } else if (outlen == 0 ) {
data_direction = SCSI_DATA_WRITE; data_direction = DMA_TO_DEVICE;
} else { } else {
/* /*
* Can this ever happen? * Can this ever happen?
*/ */
data_direction = SCSI_DATA_UNKNOWN; data_direction = DMA_BIDIRECTIONAL;
} }
} else { } else {
buf = NULL; buf = NULL;
data_direction = SCSI_DATA_NONE; data_direction = DMA_NONE;
} }
/* /*
...@@ -322,7 +322,7 @@ int scsi_ioctl_send_command(struct scsi_device *sdev, ...@@ -322,7 +322,7 @@ int scsi_ioctl_send_command(struct scsi_device *sdev,
} }
sreq = scsi_allocate_request(sdev); sreq = scsi_allocate_request(sdev);
if (sreq) { if (!sreq) {
result = -EINTR; result = -EINTR;
goto error; goto error;
} }
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include "scsi.h" #include "scsi.h"
#include "hosts.h" #include "hosts.h"
#include <scsi/scsi_driver.h>
#include "scsi_priv.h" #include "scsi_priv.h"
#include "scsi_logging.h" #include "scsi_logging.h"
...@@ -1094,14 +1095,17 @@ static inline int scsi_host_queue_ready(struct request_queue *q, ...@@ -1094,14 +1095,17 @@ static inline int scsi_host_queue_ready(struct request_queue *q,
return 0; return 0;
} }
} }
if (!list_empty(&sdev->starved_entry))
return 0;
if ((shost->can_queue > 0 && shost->host_busy >= shost->can_queue) || if ((shost->can_queue > 0 && shost->host_busy >= shost->can_queue) ||
shost->host_blocked || shost->host_self_blocked) { shost->host_blocked || shost->host_self_blocked) {
list_add_tail(&sdev->starved_entry, &shost->starved_list); if (list_empty(&sdev->starved_entry))
list_add_tail(&sdev->starved_entry, &shost->starved_list);
return 0; return 0;
} }
/* We're OK to process the command, so we can't be starved */
if (!list_empty(&sdev->starved_entry))
list_del_init(&sdev->starved_entry);
return 1; return 1;
} }
...@@ -1128,6 +1132,7 @@ static void scsi_request_fn(struct request_queue *q) ...@@ -1128,6 +1132,7 @@ static void scsi_request_fn(struct request_queue *q)
* the host is no longer able to accept any more requests. * the host is no longer able to accept any more requests.
*/ */
while (!blk_queue_plugged(q)) { while (!blk_queue_plugged(q)) {
int rtn;
/* /*
* get next queueable request. We do this early to make sure * get next queueable request. We do this early to make sure
* that the request is fully prepared even if we cannot * that the request is fully prepared even if we cannot
...@@ -1181,8 +1186,17 @@ static void scsi_request_fn(struct request_queue *q) ...@@ -1181,8 +1186,17 @@ static void scsi_request_fn(struct request_queue *q)
/* /*
* Dispatch the command to the low-level driver. * Dispatch the command to the low-level driver.
*/ */
scsi_dispatch_cmd(cmd); rtn = scsi_dispatch_cmd(cmd);
spin_lock_irq(q->queue_lock); spin_lock_irq(q->queue_lock);
if(rtn) {
/* we're refusing the command; because of
* the way locks get dropped, we need to
* check here if plugging is required */
if(sdev->device_busy == 0)
blk_plug_device(q);
break;
}
} }
return; return;
...@@ -1203,6 +1217,8 @@ static void scsi_request_fn(struct request_queue *q) ...@@ -1203,6 +1217,8 @@ static void scsi_request_fn(struct request_queue *q)
blk_queue_end_tag(q, req); blk_queue_end_tag(q, req);
__elv_add_request(q, req, 0, 0); __elv_add_request(q, req, 0, 0);
sdev->device_busy--; sdev->device_busy--;
if(sdev->device_busy == 0)
blk_plug_device(q);
} }
u64 scsi_calculate_bounce_limit(struct Scsi_Host *shost) u64 scsi_calculate_bounce_limit(struct Scsi_Host *shost)
...@@ -1336,3 +1352,127 @@ void scsi_exit_queue(void) ...@@ -1336,3 +1352,127 @@ void scsi_exit_queue(void)
kmem_cache_destroy(sgp->slab); kmem_cache_destroy(sgp->slab);
} }
} }
/**
* __scsi_mode_sense - issue a mode sense, falling back from 10 to
* six bytes if necessary.
* @sreq: SCSI request to fill in with the MODE_SENSE
* @dbd: set if mode sense will allow block descriptors to be returned
* @modepage: mode page being requested
* @buffer: request buffer (may not be smaller than eight bytes)
* @len: length of request buffer.
* @timeout: command timeout
* @retries: number of retries before failing
* @data: returns a structure abstracting the mode header data
*
* Returns zero if unsuccessful, or the header offset (either 4
* or 8 depending on whether a six or ten byte command was
* issued) if successful.
**/
int
__scsi_mode_sense(struct scsi_request *sreq, int dbd, int modepage,
unsigned char *buffer, int len, int timeout, int retries,
struct scsi_mode_data *data) {
unsigned char cmd[12];
int use_10_for_ms;
int header_length;
memset(data, 0, sizeof(*data));
memset(&cmd[0], 0, 12);
cmd[1] = dbd & 0x18; /* allows DBD and LLBA bits */
cmd[2] = modepage;
retry:
use_10_for_ms = sreq->sr_device->use_10_for_ms;
if (use_10_for_ms) {
if (len < 8)
len = 8;
cmd[0] = MODE_SENSE_10;
cmd[8] = len;
header_length = 8;
} else {
if (len < 4)
len = 4;
cmd[0] = MODE_SENSE;
cmd[4] = len;
header_length = 4;
}
sreq->sr_cmd_len = 0;
sreq->sr_sense_buffer[0] = 0;
sreq->sr_sense_buffer[2] = 0;
sreq->sr_data_direction = DMA_FROM_DEVICE;
memset(buffer, 0, len);
scsi_wait_req(sreq, cmd, buffer, len, timeout, retries);
/* This code looks awful: what it's doing is making sure an
* ILLEGAL REQUEST sense return identifies the actual command
* byte as the problem. MODE_SENSE commands can return
* ILLEGAL REQUEST if the code page isn't supported */
if (use_10_for_ms && ! scsi_status_is_good(sreq->sr_result) &&
(driver_byte(sreq->sr_result) & DRIVER_SENSE) &&
sreq->sr_sense_buffer[2] == ILLEGAL_REQUEST &&
(sreq->sr_sense_buffer[4] & 0x40) == 0x40 &&
sreq->sr_sense_buffer[5] == 0 &&
sreq->sr_sense_buffer[6] == 0 ) {
sreq->sr_device->use_10_for_ms = 0;
goto retry;
}
if(scsi_status_is_good(sreq->sr_result)) {
data->header_length = header_length;
if(use_10_for_ms) {
data->length = buffer[0]*256 + buffer[1];
data->medium_type = buffer[2];
data->device_specific = buffer[3];
data->longlba = buffer[4] & 0x01;
data->block_descriptor_length = buffer[6]*256
+ buffer[7];
} else {
data->length = buffer[0];
data->medium_type = buffer[1];
data->device_specific = buffer[3];
data->block_descriptor_length = buffer[4];
}
}
return sreq->sr_result;
}
/**
* scsi_mode_sense - issue a mode sense, falling back from 10 to
* six bytes if necessary.
* @sdev: scsi device to send command to.
* @dbd: set if mode sense will disable block descriptors in the return
* @modepage: mode page being requested
* @buffer: request buffer (may not be smaller than eight bytes)
* @len: length of request buffer.
* @timeout: command timeout
* @retries: number of retries before failing
*
* Returns zero if unsuccessful, or the header offset (either 4
* or 8 depending on whether a six or ten byte command was
* issued) if successful.
**/
int
scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage,
unsigned char *buffer, int len, int timeout, int retries,
struct scsi_mode_data *data)
{
struct scsi_request *sreq = scsi_allocate_request(sdev);
int ret;
if (!sreq)
return -1;
ret = __scsi_mode_sense(sreq, dbd, modepage, buffer, len,
timeout, retries, data);
scsi_release_request(sreq);
return ret;
}
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include "scsi.h" #include "scsi.h"
#include "hosts.h" #include "hosts.h"
#include <scsi/scsi_driver.h>
#include "scsi_priv.h" #include "scsi_priv.h"
#include "scsi_logging.h" #include "scsi_logging.h"
...@@ -116,7 +117,7 @@ static void scsi_unlock_floptical(struct scsi_request *sreq, ...@@ -116,7 +117,7 @@ static void scsi_unlock_floptical(struct scsi_request *sreq,
scsi_cmd[4] = 0x2a; /* size */ scsi_cmd[4] = 0x2a; /* size */
scsi_cmd[5] = 0; scsi_cmd[5] = 0;
sreq->sr_cmd_len = 0; sreq->sr_cmd_len = 0;
sreq->sr_data_direction = SCSI_DATA_READ; sreq->sr_data_direction = DMA_FROM_DEVICE;
scsi_wait_req(sreq, scsi_cmd, result, 0x2a /* size */, SCSI_TIMEOUT, 3); scsi_wait_req(sreq, scsi_cmd, result, 0x2a /* size */, SCSI_TIMEOUT, 3);
} }
...@@ -333,7 +334,7 @@ static void scsi_probe_lun(struct scsi_request *sreq, char *inq_result, ...@@ -333,7 +334,7 @@ static void scsi_probe_lun(struct scsi_request *sreq, char *inq_result,
scsi_cmd[0] = INQUIRY; scsi_cmd[0] = INQUIRY;
scsi_cmd[4] = 36; /* issue conservative alloc_length */ scsi_cmd[4] = 36; /* issue conservative alloc_length */
sreq->sr_cmd_len = 0; sreq->sr_cmd_len = 0;
sreq->sr_data_direction = SCSI_DATA_READ; sreq->sr_data_direction = DMA_FROM_DEVICE;
memset(inq_result, 0, 36); memset(inq_result, 0, 36);
scsi_wait_req(sreq, (void *) scsi_cmd, (void *) inq_result, 36, scsi_wait_req(sreq, (void *) scsi_cmd, (void *) inq_result, 36,
...@@ -379,7 +380,7 @@ static void scsi_probe_lun(struct scsi_request *sreq, char *inq_result, ...@@ -379,7 +380,7 @@ static void scsi_probe_lun(struct scsi_request *sreq, char *inq_result,
scsi_cmd[0] = INQUIRY; scsi_cmd[0] = INQUIRY;
scsi_cmd[4] = (unsigned char) possible_inq_resp_len; scsi_cmd[4] = (unsigned char) possible_inq_resp_len;
sreq->sr_cmd_len = 0; sreq->sr_cmd_len = 0;
sreq->sr_data_direction = SCSI_DATA_READ; sreq->sr_data_direction = DMA_FROM_DEVICE;
/* /*
* re-zero inq_result just to be safe. * re-zero inq_result just to be safe.
*/ */
...@@ -940,7 +941,7 @@ static int scsi_report_lun_scan(struct scsi_device *sdev, int bflags) ...@@ -940,7 +941,7 @@ static int scsi_report_lun_scan(struct scsi_device *sdev, int bflags)
scsi_cmd[10] = 0; /* reserved */ scsi_cmd[10] = 0; /* reserved */
scsi_cmd[11] = 0; /* control */ scsi_cmd[11] = 0; /* control */
sreq->sr_cmd_len = 0; sreq->sr_cmd_len = 0;
sreq->sr_data_direction = SCSI_DATA_READ; sreq->sr_data_direction = DMA_FROM_DEVICE;
/* /*
* We can get a UNIT ATTENTION, for example a power on/reset, so * We can get a UNIT ATTENTION, for example a power on/reset, so
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include <asm/dma.h> #include <asm/dma.h>
#include "scsi.h" #include "scsi.h"
#include <scsi/scsi_driver.h>
#include <scsi/scsi_ioctl.h> #include <scsi/scsi_ioctl.h>
#include "hosts.h" #include "hosts.h"
#include "scsi_logging.h" #include "scsi_logging.h"
...@@ -86,6 +87,9 @@ EXPORT_SYMBOL(scsi_add_device); ...@@ -86,6 +87,9 @@ EXPORT_SYMBOL(scsi_add_device);
EXPORT_SYMBOL(scsi_remove_device); EXPORT_SYMBOL(scsi_remove_device);
EXPORT_SYMBOL(scsi_set_device_offline); EXPORT_SYMBOL(scsi_set_device_offline);
EXPORT_SYMBOL(__scsi_mode_sense);
EXPORT_SYMBOL(scsi_mode_sense);
/* /*
* This symbol is for the highlevel drivers (e.g. sg) only. * This symbol is for the highlevel drivers (e.g. sg) only.
*/ */
......
...@@ -194,20 +194,14 @@ sdev_rd_attr (model, "%.16s\n"); ...@@ -194,20 +194,14 @@ sdev_rd_attr (model, "%.16s\n");
sdev_rd_attr (rev, "%.4s\n"); sdev_rd_attr (rev, "%.4s\n");
sdev_rw_attr_bit (online); sdev_rw_attr_bit (online);
static ssize_t
show_rescan_field (struct device *dev, char *buf)
{
return 0;
}
static ssize_t static ssize_t
store_rescan_field (struct device *dev, const char *buf, size_t count) store_rescan_field (struct device *dev, const char *buf, size_t count)
{ {
scsi_rescan_device(dev); scsi_rescan_device(dev);
return 0; return count;
} }
static DEVICE_ATTR(rescan, S_IRUGO | S_IWUSR, show_rescan_field, store_rescan_field) static DEVICE_ATTR(rescan, S_IWUSR, NULL, store_rescan_field)
/* Default template for device attributes. May NOT be modified */ /* Default template for device attributes. May NOT be modified */
struct device_attribute *scsi_sysfs_sdev_attrs[] = { struct device_attribute *scsi_sysfs_sdev_attrs[] = {
...@@ -388,30 +382,36 @@ void scsi_sysfs_remove_host(struct Scsi_Host *shost) ...@@ -388,30 +382,36 @@ void scsi_sysfs_remove_host(struct Scsi_Host *shost)
* *
* returns zero if successful or error if not * returns zero if successful or error if not
**/ **/
int scsi_sysfs_modify_shost_attribute(struct class_device_attribute ***class_attrs, int scsi_sysfs_modify_shost_attribute(
struct class_device_attribute *attr) struct class_device_attribute ***class_attrs,
struct class_device_attribute *attr)
{ {
int modify = 0; int modify = -1;
int num_attrs; int num_attrs;
if(*class_attrs == NULL) if(*class_attrs == NULL)
*class_attrs = scsi_sysfs_shost_attrs; *class_attrs = scsi_sysfs_shost_attrs;
for(num_attrs=0; (*class_attrs)[num_attrs] != NULL; num_attrs++) for(num_attrs=0; (*class_attrs)[num_attrs] != NULL; num_attrs++)
if(strcmp((*class_attrs)[num_attrs]->attr.name, attr->attr.name) == 0) if(strcmp((*class_attrs)[num_attrs]->attr.name,
attr->attr.name) == 0)
modify = num_attrs; modify = num_attrs;
if(*class_attrs == scsi_sysfs_shost_attrs || !modify) { if(*class_attrs == scsi_sysfs_shost_attrs || modify < 0) {
/* note: need space for null at the end as well */ /* note: need space for null at the end as well */
struct class_device_attribute **tmp_attrs = kmalloc(sizeof(struct class_device_attribute)*(num_attrs + (modify ? 1 : 2)), GFP_KERNEL); struct class_device_attribute **tmp_attrs =
kmalloc(sizeof(*tmp_attrs) *
(num_attrs + (modify >= 0 ? 1 : 2)),
GFP_KERNEL);
if(tmp_attrs == NULL) if(tmp_attrs == NULL)
return -ENOMEM; return -ENOMEM;
memcpy(tmp_attrs, *class_attrs, sizeof(struct class_device_attribute)*num_attrs); memcpy(tmp_attrs, *class_attrs, sizeof(*tmp_attrs) *
(num_attrs + 1));
if(*class_attrs != scsi_sysfs_shost_attrs) if(*class_attrs != scsi_sysfs_shost_attrs)
kfree(*class_attrs); kfree(*class_attrs);
*class_attrs = tmp_attrs; *class_attrs = tmp_attrs;
} }
if(modify) { if(modify >= 0) {
/* spare the caller from having to copy things it's /* spare the caller from having to copy things it's
* not interested in */ * not interested in */
struct class_device_attribute *old_attr = struct class_device_attribute *old_attr =
...@@ -444,27 +444,32 @@ EXPORT_SYMBOL(scsi_sysfs_modify_shost_attribute); ...@@ -444,27 +444,32 @@ EXPORT_SYMBOL(scsi_sysfs_modify_shost_attribute);
int scsi_sysfs_modify_sdev_attribute(struct device_attribute ***dev_attrs, int scsi_sysfs_modify_sdev_attribute(struct device_attribute ***dev_attrs,
struct device_attribute *attr) struct device_attribute *attr)
{ {
int modify = 0; int modify = -1;
int num_attrs; int num_attrs;
if(*dev_attrs == NULL) if(*dev_attrs == NULL)
*dev_attrs = scsi_sysfs_sdev_attrs; *dev_attrs = scsi_sysfs_sdev_attrs;
for(num_attrs=0; (*dev_attrs)[num_attrs] != NULL; num_attrs++) for(num_attrs=0; (*dev_attrs)[num_attrs] != NULL; num_attrs++)
if(strcmp((*dev_attrs)[num_attrs]->attr.name, attr->attr.name) == 0) if(strcmp((*dev_attrs)[num_attrs]->attr.name,
attr->attr.name) == 0)
modify = num_attrs; modify = num_attrs;
if(*dev_attrs == scsi_sysfs_sdev_attrs || !modify) { if(*dev_attrs == scsi_sysfs_sdev_attrs || modify < 0) {
/* note: need space for null at the end as well */ /* note: need space for null at the end as well */
struct device_attribute **tmp_attrs = kmalloc(sizeof(struct device_attribute)*(num_attrs + (modify ? 1 : 2)), GFP_KERNEL); struct device_attribute **tmp_attrs =
kmalloc(sizeof(*tmp_attrs) *
(num_attrs + (modify >= 0 ? 1 : 2)),
GFP_KERNEL);
if(tmp_attrs == NULL) if(tmp_attrs == NULL)
return -ENOMEM; return -ENOMEM;
memcpy(tmp_attrs, *dev_attrs, sizeof(struct device_attribute)*num_attrs); memcpy(tmp_attrs, *dev_attrs, sizeof(*tmp_attrs) *
(num_attrs + 1));
if(*dev_attrs != scsi_sysfs_sdev_attrs) if(*dev_attrs != scsi_sysfs_sdev_attrs)
kfree(*dev_attrs); kfree(*dev_attrs);
*dev_attrs = tmp_attrs; *dev_attrs = tmp_attrs;
} }
if(modify) { if(modify >= 0) {
/* spare the caller from having to copy things it's /* spare the caller from having to copy things it's
* not interested in */ * not interested in */
struct device_attribute *old_attr = struct device_attribute *old_attr =
......
...@@ -49,6 +49,8 @@ ...@@ -49,6 +49,8 @@
#include "scsi.h" #include "scsi.h"
#include "hosts.h" #include "hosts.h"
#include <scsi/scsi_driver.h>
#include <scsi/scsi_ioctl.h> #include <scsi/scsi_ioctl.h>
#include <scsi/scsicam.h> #include <scsi/scsicam.h>
...@@ -161,11 +163,11 @@ static int sd_init_command(struct scsi_cmnd * SCpnt) ...@@ -161,11 +163,11 @@ static int sd_init_command(struct scsi_cmnd * SCpnt)
memcpy(SCpnt->cmnd, rq->cmd, sizeof(SCpnt->cmnd)); memcpy(SCpnt->cmnd, rq->cmd, sizeof(SCpnt->cmnd));
if (rq_data_dir(rq) == WRITE) if (rq_data_dir(rq) == WRITE)
SCpnt->sc_data_direction = SCSI_DATA_WRITE; SCpnt->sc_data_direction = DMA_TO_DEVICE;
else if (rq->data_len) else if (rq->data_len)
SCpnt->sc_data_direction = SCSI_DATA_READ; SCpnt->sc_data_direction = DMA_FROM_DEVICE;
else else
SCpnt->sc_data_direction = SCSI_DATA_NONE; SCpnt->sc_data_direction = DMA_NONE;
this_count = rq->data_len; this_count = rq->data_len;
if (rq->timeout) if (rq->timeout)
...@@ -251,10 +253,10 @@ static int sd_init_command(struct scsi_cmnd * SCpnt) ...@@ -251,10 +253,10 @@ static int sd_init_command(struct scsi_cmnd * SCpnt)
return 0; return 0;
} }
SCpnt->cmnd[0] = WRITE_6; SCpnt->cmnd[0] = WRITE_6;
SCpnt->sc_data_direction = SCSI_DATA_WRITE; SCpnt->sc_data_direction = DMA_TO_DEVICE;
} else if (rq_data_dir(SCpnt->request) == READ) { } else if (rq_data_dir(SCpnt->request) == READ) {
SCpnt->cmnd[0] = READ_6; SCpnt->cmnd[0] = READ_6;
SCpnt->sc_data_direction = SCSI_DATA_READ; SCpnt->sc_data_direction = DMA_FROM_DEVICE;
} else { } else {
printk(KERN_ERR "sd: Unknown command %lx\n", printk(KERN_ERR "sd: Unknown command %lx\n",
SCpnt->request->flags); SCpnt->request->flags);
...@@ -790,7 +792,7 @@ sd_spinup_disk(struct scsi_disk *sdkp, char *diskname, ...@@ -790,7 +792,7 @@ sd_spinup_disk(struct scsi_disk *sdkp, char *diskname,
SRpnt->sr_cmd_len = 0; SRpnt->sr_cmd_len = 0;
SRpnt->sr_sense_buffer[0] = 0; SRpnt->sr_sense_buffer[0] = 0;
SRpnt->sr_sense_buffer[2] = 0; SRpnt->sr_sense_buffer[2] = 0;
SRpnt->sr_data_direction = SCSI_DATA_NONE; SRpnt->sr_data_direction = DMA_NONE;
scsi_wait_req (SRpnt, (void *) cmd, (void *) buffer, scsi_wait_req (SRpnt, (void *) cmd, (void *) buffer,
0/*512*/, SD_TIMEOUT, SD_MAX_RETRIES); 0/*512*/, SD_TIMEOUT, SD_MAX_RETRIES);
...@@ -850,7 +852,7 @@ sd_spinup_disk(struct scsi_disk *sdkp, char *diskname, ...@@ -850,7 +852,7 @@ sd_spinup_disk(struct scsi_disk *sdkp, char *diskname,
SRpnt->sr_sense_buffer[0] = 0; SRpnt->sr_sense_buffer[0] = 0;
SRpnt->sr_sense_buffer[2] = 0; SRpnt->sr_sense_buffer[2] = 0;
SRpnt->sr_data_direction = SCSI_DATA_NONE; SRpnt->sr_data_direction = DMA_NONE;
scsi_wait_req(SRpnt, (void *)cmd, scsi_wait_req(SRpnt, (void *)cmd,
(void *) buffer, 0/*512*/, (void *) buffer, 0/*512*/,
SD_TIMEOUT, SD_MAX_RETRIES); SD_TIMEOUT, SD_MAX_RETRIES);
...@@ -915,7 +917,7 @@ sd_read_capacity(struct scsi_disk *sdkp, char *diskname, ...@@ -915,7 +917,7 @@ sd_read_capacity(struct scsi_disk *sdkp, char *diskname,
SRpnt->sr_cmd_len = 0; SRpnt->sr_cmd_len = 0;
SRpnt->sr_sense_buffer[0] = 0; SRpnt->sr_sense_buffer[0] = 0;
SRpnt->sr_sense_buffer[2] = 0; SRpnt->sr_sense_buffer[2] = 0;
SRpnt->sr_data_direction = SCSI_DATA_READ; SRpnt->sr_data_direction = DMA_FROM_DEVICE;
scsi_wait_req(SRpnt, (void *) cmd, (void *) buffer, scsi_wait_req(SRpnt, (void *) cmd, (void *) buffer,
longrc ? 12 : 8, SD_TIMEOUT, SD_MAX_RETRIES); longrc ? 12 : 8, SD_TIMEOUT, SD_MAX_RETRIES);
...@@ -1062,40 +1064,12 @@ sd_read_capacity(struct scsi_disk *sdkp, char *diskname, ...@@ -1062,40 +1064,12 @@ sd_read_capacity(struct scsi_disk *sdkp, char *diskname,
} }
/* called with buffer of length 512 */ /* called with buffer of length 512 */
static int static inline int
sd_do_mode_sense(struct scsi_request *SRpnt, int dbd, int modepage, sd_do_mode_sense(struct scsi_request *SRpnt, int dbd, int modepage,
unsigned char *buffer, int len) { unsigned char *buffer, int len, struct scsi_mode_data *data)
unsigned char cmd[12]; {
return __scsi_mode_sense(SRpnt, dbd, modepage, buffer, len,
memset((void *) &cmd[0], 0, 12); SD_TIMEOUT, SD_MAX_RETRIES, data);
cmd[1] = dbd;
cmd[2] = modepage;
if (SRpnt->sr_device->use_10_for_ms) {
if (len < 8)
len = 8;
cmd[0] = MODE_SENSE_10;
cmd[8] = len;
} else {
if (len < 4)
len = 4;
cmd[0] = MODE_SENSE;
cmd[4] = len;
}
SRpnt->sr_cmd_len = 0;
SRpnt->sr_sense_buffer[0] = 0;
SRpnt->sr_sense_buffer[2] = 0;
SRpnt->sr_data_direction = SCSI_DATA_READ;
memset((void *) buffer, 0, len);
scsi_wait_req(SRpnt, (void *) cmd, (void *) buffer,
len, SD_TIMEOUT, SD_MAX_RETRIES);
return SRpnt->sr_result;
} }
/* /*
...@@ -1106,33 +1080,34 @@ static void ...@@ -1106,33 +1080,34 @@ static void
sd_read_write_protect_flag(struct scsi_disk *sdkp, char *diskname, sd_read_write_protect_flag(struct scsi_disk *sdkp, char *diskname,
struct scsi_request *SRpnt, unsigned char *buffer) { struct scsi_request *SRpnt, unsigned char *buffer) {
int res; int res;
struct scsi_mode_data data;
/* /*
* First attempt: ask for all pages (0x3F), but only 4 bytes. * First attempt: ask for all pages (0x3F), but only 4 bytes.
* We have to start carefully: some devices hang if we ask * We have to start carefully: some devices hang if we ask
* for more than is available. * for more than is available.
*/ */
res = sd_do_mode_sense(SRpnt, 0, 0x3F, buffer, 4); res = sd_do_mode_sense(SRpnt, 0, 0x3F, buffer, 4, &data);
/* /*
* Second attempt: ask for page 0 * Second attempt: ask for page 0
* When only page 0 is implemented, a request for page 3F may return * When only page 0 is implemented, a request for page 3F may return
* Sense Key 5: Illegal Request, Sense Code 24: Invalid field in CDB. * Sense Key 5: Illegal Request, Sense Code 24: Invalid field in CDB.
*/ */
if (res) if (!scsi_status_is_good(res))
res = sd_do_mode_sense(SRpnt, 0, 0, buffer, 4); res = sd_do_mode_sense(SRpnt, 0, 0, buffer, 4, &data);
/* /*
* Third attempt: ask 255 bytes, as we did earlier. * Third attempt: ask 255 bytes, as we did earlier.
*/ */
if (res) if (!scsi_status_is_good(res))
res = sd_do_mode_sense(SRpnt, 0, 0x3F, buffer, 255); res = sd_do_mode_sense(SRpnt, 0, 0x3F, buffer, 255, &data);
if (res) { if (!scsi_status_is_good(res)) {
printk(KERN_WARNING printk(KERN_WARNING
"%s: test WP failed, assume Write Enabled\n", diskname); "%s: test WP failed, assume Write Enabled\n", diskname);
} else { } else {
sdkp->write_prot = ((buffer[2] & 0x80) != 0); sdkp->write_prot = ((data.device_specific & 0x80) != 0);
printk(KERN_NOTICE "%s: Write Protect is %s\n", diskname, printk(KERN_NOTICE "%s: Write Protect is %s\n", diskname,
sdkp->write_prot ? "on" : "off"); sdkp->write_prot ? "on" : "off");
printk(KERN_DEBUG "%s: Mode Sense: %02x %02x %02x %02x\n", printk(KERN_DEBUG "%s: Mode Sense: %02x %02x %02x %02x\n",
...@@ -1149,43 +1124,45 @@ sd_read_cache_type(struct scsi_disk *sdkp, char *diskname, ...@@ -1149,43 +1124,45 @@ sd_read_cache_type(struct scsi_disk *sdkp, char *diskname,
struct scsi_request *SRpnt, unsigned char *buffer) { struct scsi_request *SRpnt, unsigned char *buffer) {
int len = 0, res; int len = 0, res;
const int dbd = 0x08; /* DBD */ const int dbd = 0; /* DBD */
const int modepage = 0x08; /* current values, cache page */ const int modepage = 0x08; /* current values, cache page */
struct scsi_mode_data data;
/* cautiously ask */ /* cautiously ask */
res = sd_do_mode_sense(SRpnt, dbd, modepage, buffer, 4); res = sd_do_mode_sense(SRpnt, dbd, modepage, buffer, 4, &data);
if (res == 0) { if (scsi_status_is_good(res)) {
/* that went OK, now ask for the proper length */ /* that went OK, now ask for the proper length */
len = buffer[0] + 1; len = data.length;
if (len > 128) if (len > 128)
len = 128; len = 128;
res = sd_do_mode_sense(SRpnt, dbd, modepage, buffer, len); res = sd_do_mode_sense(SRpnt, dbd, modepage, buffer,
len, &data);
} }
if (res == 0 && buffer[3] + 6 < len) { if (scsi_status_is_good(res)) {
const char *types[] = { const char *types[] = {
"write through", "none", "write back", "write through", "none", "write back",
"write back, no read (daft)" "write back, no read (daft)"
}; };
int ct = 0; int ct = 0;
int offset = buffer[3] + 4; /* start of mode page */ int offset = data.header_length +
data.block_descriptor_length + 2;
sdkp->WCE = ((buffer[offset + 2] & 0x04) != 0); sdkp->WCE = ((buffer[offset] & 0x04) != 0);
sdkp->RCD = ((buffer[offset + 2] & 0x01) != 0); sdkp->RCD = ((buffer[offset] & 0x01) != 0);
ct = sdkp->RCD + 2*sdkp->WCE; ct = sdkp->RCD + 2*sdkp->WCE;
printk(KERN_NOTICE "SCSI device %s: drive cache: %s\n", printk(KERN_NOTICE "SCSI device %s: drive cache: %s\n",
diskname, types[ct]); diskname, types[ct]);
} else { } else {
if (res == 0 || if ((SRpnt->sr_sense_buffer[0] & 0x70) == 0x70
(status_byte(res) == CHECK_CONDITION
&& (SRpnt->sr_sense_buffer[0] & 0x70) == 0x70
&& (SRpnt->sr_sense_buffer[2] & 0x0f) == ILLEGAL_REQUEST && (SRpnt->sr_sense_buffer[2] & 0x0f) == ILLEGAL_REQUEST
/* ASC 0x24 ASCQ 0x00: Invalid field in CDB */ /* ASC 0x24 ASCQ 0x00: Invalid field in CDB */
&& SRpnt->sr_sense_buffer[12] == 0x24 && SRpnt->sr_sense_buffer[12] == 0x24
&& SRpnt->sr_sense_buffer[13] == 0x00)) { && SRpnt->sr_sense_buffer[13] == 0x00) {
printk(KERN_NOTICE "%s: cache data unavailable\n", printk(KERN_NOTICE "%s: cache data unavailable\n",
diskname); diskname);
} else { } else {
...@@ -1417,7 +1394,7 @@ static void sd_shutdown(struct device *dev) ...@@ -1417,7 +1394,7 @@ static void sd_shutdown(struct device *dev)
return; return;
} }
sreq->sr_data_direction = SCSI_DATA_NONE; sreq->sr_data_direction = DMA_NONE;
for (retries = 3; retries > 0; --retries) { for (retries = 3; retries > 0; --retries) {
unsigned char cmd[10] = { 0 }; unsigned char cmd[10] = { 0 };
......
...@@ -266,20 +266,6 @@ MODULE_LICENSE("GPL"); ...@@ -266,20 +266,6 @@ MODULE_LICENSE("GPL");
#define WRITE_CONTROL(d) { isa_writeb((d), st0x_cr_sr); } #define WRITE_CONTROL(d) { isa_writeb((d), st0x_cr_sr); }
#define WRITE_DATA(d) { isa_writeb((d), st0x_dr); } #define WRITE_DATA(d) { isa_writeb((d), st0x_dr); }
static void st0x_setup (char *str, int *ints)
{
controller_type = SEAGATE;
base_address = ints[1];
irq = ints[2];
}
static void tmc8xx_setup (char *str, int *ints)
{
controller_type = FD;
base_address = ints[1];
irq = ints[2];
}
#ifndef OVERRIDE #ifndef OVERRIDE
static unsigned int seagate_bases[] = { static unsigned int seagate_bases[] = {
0xc8000, 0xca000, 0xcc000, 0xc8000, 0xca000, 0xcc000,
......
...@@ -10,7 +10,6 @@ ...@@ -10,7 +10,6 @@
#define SEAGATE_H #define SEAGATE_H
static int seagate_st0x_detect(Scsi_Host_Template *); static int seagate_st0x_detect(Scsi_Host_Template *);
static int seagate_st0x_command(Scsi_Cmnd *);
static int seagate_st0x_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); static int seagate_st0x_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
static int seagate_st0x_abort(Scsi_Cmnd *); static int seagate_st0x_abort(Scsi_Cmnd *);
......
...@@ -64,6 +64,7 @@ static int sg_version_num = 30529; /* 2 digits for each component */ ...@@ -64,6 +64,7 @@ static int sg_version_num = 30529; /* 2 digits for each component */
#include <linux/blk.h> #include <linux/blk.h>
#include "scsi.h" #include "scsi.h"
#include "hosts.h" #include "hosts.h"
#include <scsi/scsi_driver.h>
#include <scsi/scsi_ioctl.h> #include <scsi/scsi_ioctl.h>
#include <scsi/sg.h> #include <scsi/sg.h>
......
...@@ -48,6 +48,8 @@ ...@@ -48,6 +48,8 @@
#include "scsi.h" #include "scsi.h"
#include "hosts.h" #include "hosts.h"
#include <scsi/scsi_driver.h>
#include <scsi/scsi_ioctl.h> /* For the door lock/unlock commands */ #include <scsi/scsi_ioctl.h> /* For the door lock/unlock commands */
#include "scsi_logging.h" #include "scsi_logging.h"
...@@ -660,9 +662,9 @@ static void get_sectorsize(struct scsi_cd *cd) ...@@ -660,9 +662,9 @@ static void get_sectorsize(struct scsi_cd *cd)
static void get_capabilities(struct scsi_cd *cd) static void get_capabilities(struct scsi_cd *cd)
{ {
struct cdrom_generic_command cgc;
unsigned char *buffer; unsigned char *buffer;
int rc, n; int rc, n;
struct scsi_mode_data data;
static char *loadmech[] = static char *loadmech[] =
{ {
...@@ -681,18 +683,10 @@ static void get_capabilities(struct scsi_cd *cd) ...@@ -681,18 +683,10 @@ static void get_capabilities(struct scsi_cd *cd)
printk(KERN_ERR "sr: out of memory.\n"); printk(KERN_ERR "sr: out of memory.\n");
return; return;
} }
memset(&cgc, 0, sizeof(struct cdrom_generic_command)); rc = scsi_mode_sense(cd->device, 0, 0x2a, buffer, 128,
cgc.cmd[0] = MODE_SENSE; SR_TIMEOUT, 3, &data);
cgc.cmd[2] = 0x2a;
cgc.cmd[4] = 128; if (!scsi_status_is_good(rc)) {
cgc.buffer = buffer;
cgc.buflen = 128;
cgc.quiet = 1;
cgc.data_direction = SCSI_DATA_READ;
cgc.timeout = SR_TIMEOUT;
rc = sr_do_ioctl(cd, &cgc);
if (rc) {
/* failed, drive doesn't have capabilities mode page */ /* failed, drive doesn't have capabilities mode page */
cd->cdi.speed = 1; cd->cdi.speed = 1;
cd->cdi.mask |= (CDC_CD_R | CDC_CD_RW | CDC_DVD_R | cd->cdi.mask |= (CDC_CD_R | CDC_CD_RW | CDC_DVD_R |
...@@ -702,7 +696,7 @@ static void get_capabilities(struct scsi_cd *cd) ...@@ -702,7 +696,7 @@ static void get_capabilities(struct scsi_cd *cd)
printk("%s: scsi-1 drive\n", cd->cdi.name); printk("%s: scsi-1 drive\n", cd->cdi.name);
return; return;
} }
n = buffer[3] + 4; n = data.header_length + data.block_descriptor_length;
cd->cdi.speed = ((buffer[n + 8] << 8) + buffer[n + 9]) / 176; cd->cdi.speed = ((buffer[n + 8] << 8) + buffer[n + 9]) / 176;
cd->readcd_known = 1; cd->readcd_known = 1;
cd->readcd_cdda = buffer[n + 5] & 0x01; cd->readcd_cdda = buffer[n + 5] & 0x01;
......
...@@ -58,6 +58,8 @@ static char *verstr = "20030622"; ...@@ -58,6 +58,8 @@ static char *verstr = "20030622";
#include "scsi.h" #include "scsi.h"
#include "hosts.h" #include "hosts.h"
#include <scsi/scsi_driver.h>
#include <scsi/scsi_ioctl.h> #include <scsi/scsi_ioctl.h>
#define ST_KILOBYTE 1024 #define ST_KILOBYTE 1024
......
...@@ -25,7 +25,6 @@ ...@@ -25,7 +25,6 @@
static int sym53c416_detect(Scsi_Host_Template *); static int sym53c416_detect(Scsi_Host_Template *);
static const char *sym53c416_info(struct Scsi_Host *); static const char *sym53c416_info(struct Scsi_Host *);
static int sym53c416_release(struct Scsi_Host *); static int sym53c416_release(struct Scsi_Host *);
static int sym53c416_command(Scsi_Cmnd *);
static int sym53c416_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); static int sym53c416_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
static int sym53c416_abort(Scsi_Cmnd *); static int sym53c416_abort(Scsi_Cmnd *);
static int sym53c416_host_reset(Scsi_Cmnd *); static int sym53c416_host_reset(Scsi_Cmnd *);
......
...@@ -295,12 +295,8 @@ struct host_data { ...@@ -295,12 +295,8 @@ struct host_data {
#ifndef SYM_LINUX_DYNAMIC_DMA_MAPPING #ifndef SYM_LINUX_DYNAMIC_DMA_MAPPING
typedef u_long bus_addr_t; typedef u_long bus_addr_t;
#else #else
#if SYM_CONF_DMA_ADDRESSING_MODE > 0
typedef dma64_addr_t bus_addr_t;
#else
typedef dma_addr_t bus_addr_t; typedef dma_addr_t bus_addr_t;
#endif #endif
#endif
/* /*
* Used by the eh thread to wait for command completion. * Used by the eh thread to wait for command completion.
...@@ -1863,7 +1859,7 @@ static int sym_setup_bus_dma_mask(hcb_p np) ...@@ -1863,7 +1859,7 @@ static int sym_setup_bus_dma_mask(hcb_p np)
#if SYM_CONF_DMA_ADDRESSING_MODE == 1 #if SYM_CONF_DMA_ADDRESSING_MODE == 1
#define PciDmaMask 0xffffffffff #define PciDmaMask 0xffffffffff
#elif SYM_CONF_DMA_ADDRESSING_MODE == 2 #elif SYM_CONF_DMA_ADDRESSING_MODE == 2
#define PciDmaMask 0xffffffffffffffff #define PciDmaMask 0xffffffffffffffffULL
#endif #endif
if (np->features & FE_DAC) { if (np->features & FE_DAC) {
if (!pci_set_dma_mask(np->s.device, PciDmaMask)) { if (!pci_set_dma_mask(np->s.device, PciDmaMask)) {
...@@ -2753,14 +2749,6 @@ if (sym53c8xx) ...@@ -2753,14 +2749,6 @@ if (sym53c8xx)
/* This one is guaranteed by AC to do nothing :-) */ /* This one is guaranteed by AC to do nothing :-) */
if (pci_enable_device(pcidev)) if (pci_enable_device(pcidev))
continue; continue;
/* Some HW as the HP LH4 may report twice PCI devices */
for (i = 0; i < count ; i++) {
if (devtbl[i].s.bus == PciBusNumber(pcidev) &&
devtbl[i].s.device_fn == PciDeviceFn(pcidev))
break;
}
if (i != count) /* Ignore this device if we already have it */
continue;
devp = &devtbl[count]; devp = &devtbl[count];
devp->host_id = SYM_SETUP_HOST_ID; devp->host_id = SYM_SETUP_HOST_ID;
devp->attach_done = 0; devp->attach_done = 0;
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment