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 @@
#include <asm/byteorder.h>
#include <linux/blk.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/interrupt.h>
#include "scsi.h"
......@@ -564,8 +563,7 @@ NCR_700_unmap(struct NCR_700_Host_Parameters *hostdata, Scsi_Cmnd *SCp,
{
if(SCp->sc_data_direction != SCSI_DATA_NONE &&
SCp->sc_data_direction != SCSI_DATA_UNKNOWN) {
enum dma_data_direction direction =
(enum dma_data_direction)scsi_to_pci_dma_dir(SCp->sc_data_direction);
enum dma_data_direction direction = SCp->sc_data_direction;
if(SCp->use_sg) {
dma_unmap_sg(hostdata->dev, SCp->buffer,
SCp->use_sg, direction);
......@@ -1842,7 +1840,7 @@ NCR_700_queuecommand(Scsi_Cmnd *SCp, void (*done)(Scsi_Cmnd *))
}
/* 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) {
int i;
int sg_count;
......@@ -2039,8 +2037,15 @@ NCR_700_init(void)
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_release);
EXPORT_SYMBOL(NCR_700_intr);
module_init(NCR_700_init);
module_exit(NCR_700_exit);
......@@ -978,26 +978,16 @@ config SCSI_ZALON
used on the add-in Bluefish, Barracuda & Shrike SCSI cards.
Say Y here if you have one of these machines or cards.
config SCSI_NCR53C8XX
tristate "NCR53C8XX SCSI support"
depends on PCI && SCSI_SYM53C8XX_2!=y && SCSI_ZALON!=y && SCSI
---help---
This is the BSD ncr driver adapted to Linux for the NCR53C8XX family
of PCI-SCSI controllers. This driver supports parity checking,
tagged command queuing and fast synchronous data transfers up to 80
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".
config SCSI_NCR_Q720
tristate "NCR Quad 720 MCA SCSI support"
depends on MCA && SCSI
help
This is a driver for the MicroChannel Quad 720 card produced by
NCR and commonly used in 345x/35xx/4100 class machines. It always
tries to negotiate sync and uses tag command queueing.
Please read <file:Documentation/scsi/ncr53c8xx.txt> for more
information.
Unless you have an NCR manufactured machine, the chances are that
you do not have this SCSI card, so say N.
config SCSI_SYM53C8XX
tristate "SYM53C8XX SCSI support"
......@@ -1027,8 +1017,8 @@ config SCSI_SYM53C8XX
information.
config SCSI_NCR53C8XX_DEFAULT_TAGS
int "default tagged command queue depth"
depends on PCI && SCSI_SYM53C8XX_2!=y && (SCSI_NCR53C8XX || SCSI_SYM53C8XX || SCSI_ZALON)
int " default tagged command queue depth"
depends on (SCSI_SYM53C8XX || SCSI_ZALON || SCSI_NCR_Q720)
default "8"
---help---
"Tagged command queuing" is a feature of SCSI-2 which improves
......@@ -1053,8 +1043,8 @@ config SCSI_NCR53C8XX_DEFAULT_TAGS
There is no safe option other than using good SCSI devices.
config SCSI_NCR53C8XX_MAX_TAGS
int "maximum number of queued commands"
depends on PCI && SCSI_SYM53C8XX_2!=y && (SCSI_NCR53C8XX || SCSI_SYM53C8XX || SCSI_ZALON)
int " maximum number of queued commands"
depends on (SCSI_SYM53C8XX || SCSI_ZALON || SCSI_NCR_Q720)
default "32"
---help---
This option allows you to specify the maximum number of commands
......@@ -1070,8 +1060,8 @@ config SCSI_NCR53C8XX_MAX_TAGS
There is no safe option and the default answer is recommended.
config SCSI_NCR53C8XX_SYNC
int "synchronous transfers frequency in MHz"
depends on PCI && SCSI_SYM53C8XX_2!=y && (SCSI_NCR53C8XX || SCSI_SYM53C8XX || SCSI_ZALON)
int " synchronous transfers frequency in MHz"
depends on (SCSI_SYM53C8XX || SCSI_ZALON || SCSI_NCR_Q720)
default "20"
---help---
The SCSI Parallel Interface-2 Standard defines 5 classes of transfer
......@@ -1104,8 +1094,8 @@ config SCSI_NCR53C8XX_SYNC
terminations and SCSI conformant devices.
config SCSI_NCR53C8XX_PROFILE
bool "enable profiling"
depends on PCI && SCSI_SYM53C8XX_2!=y && (SCSI_NCR53C8XX || SCSI_SYM53C8XX || SCSI_ZALON)
bool " enable profiling"
depends on (SCSI_SYM53C8XX || SCSI_ZALON || SCSI_NCR_Q720)
help
This option allows you to enable profiling information gathering.
These statistics are not very accurate due to the low frequency
......@@ -1115,8 +1105,8 @@ config SCSI_NCR53C8XX_PROFILE
The normal answer therefore is N.
config SCSI_NCR53C8XX_IOMAPPED
bool "use normal IO"
depends on PCI && SCSI_SYM53C8XX_2!=y && (SCSI_NCR53C8XX || SCSI_SYM53C8XX) && !SCSI_ZALON
bool " use normal IO"
depends on SCSI_SYM53C8XX && !(SCSI_ZALON || SCSI_NCR_Q720)
help
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
......@@ -1128,8 +1118,8 @@ config SCSI_NCR53C8XX_IOMAPPED
related problems.
config SCSI_NCR53C8XX_PQS_PDS
bool "include support for the NCR PQS/PDS SCSI card"
depends on (SCSI_NCR53C8XX || SCSI_SYM53C8XX) && SCSI_SYM53C8XX
bool " include support for the NCR PQS/PDS SCSI card"
depends on SCSI_SYM53C8XX
help
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
......@@ -1140,8 +1130,8 @@ config SCSI_NCR53C8XX_PQS_PDS
The common answer here is N, but answering Y is safe.
config SCSI_NCR53C8XX_NO_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
bool " not allow targets to disconnect"
depends on (SCSI_SYM53C8XX || SCSI_ZALON || SCSI_NCR_Q720) && SCSI_NCR53C8XX_DEFAULT_TAGS=0
help
This option is only provided for safety if you suspect some SCSI
device of yours to not support properly the target-disconnect
......@@ -1150,8 +1140,8 @@ config SCSI_NCR53C8XX_NO_DISCONNECT
than 1 device on a SCSI bus. The normal answer therefore is N.
config SCSI_NCR53C8XX_SYMBIOS_COMPAT
bool "assume boards are SYMBIOS compatible (EXPERIMENTAL)"
depends on PCI && SCSI_SYM53C8XX_2!=y && (SCSI_NCR53C8XX || SCSI_SYM53C8XX || SCSI_ZALON) && EXPERIMENTAL
bool " assume boards are SYMBIOS compatible (EXPERIMENTAL)"
depends on (SCSI_SYM53C8XX || SCSI_ZALON || SCSI_NCR_Q720 ) && EXPERIMENTAL
---help---
This option allows you to enable some features depending on GPIO
wiring. These General Purpose Input/Output pins can be used for
......
......@@ -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_NCR53C406A) += NCR53c406a.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_QLOGIC_FAS) += qlogicfas.o
obj-$(CONFIG_SCSI_QLOGIC_ISP) += qlogicisp.o
......@@ -81,7 +82,6 @@ obj-$(CONFIG_SCSI_DMX3191D) += dmx3191d.o
obj-$(CONFIG_SCSI_DTC3280) += dtc.o
obj-$(CONFIG_SCSI_SYM53C8XX_2) += sym53c8xx_2/
obj-$(CONFIG_SCSI_SYM53C8XX) += sym53c8xx.o
obj-$(CONFIG_SCSI_NCR53C8XX) += ncr53c8xx.o
obj-$(CONFIG_SCSI_ZALON) += zalon7xx.o
obj-$(CONFIG_SCSI_EATA_PIO) += eata_pio.o
obj-$(CONFIG_SCSI_7000FASST) += wd7000.o
......@@ -133,7 +133,17 @@ sd_mod-objs := sd.o
sr_mod-objs := sr.o sr_ioctl.o sr_vendor.o
initio-objs := ini9100u.o i91uscsi.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
NCR_Q720_mod-objs := NCR_Q720.o ncr53c8xx.o
cpqfc-objs := cpqfcTSinit.o cpqfcTScontrol.o cpqfcTSi2c.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 @@
#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
/* EISA configuration registers & values */
......@@ -152,11 +147,6 @@ struct ecb { /* Enhanced Control Block 6.1 */
#define AHA1740CMD_RINQ 0x0a /* Read Host Adapter Inquiry Data */
#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_SCATTER 16
#define AHA1740_CMDLUN 1
......
......@@ -59,6 +59,7 @@
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/spinlock.h>
#include <linux/pci.h>
/*---------------------------------------------------------------------------
Features
......
......@@ -82,6 +82,13 @@ int scsi_add_host(struct Scsi_Host *shost, struct device *dev)
sht->info ? sht->info(shost) : sht->name);
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) {
scsi_proc_host_add(shost);
scsi_scan_host(shost);
......@@ -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->highmem_io = sht->highmem_io;
if (!sht->max_host_blocked)
if (sht->max_host_blocked)
shost->max_host_blocked = sht->max_host_blocked;
else
shost->max_host_blocked = SCSI_DEFAULT_HOST_BLOCKED;
......
......@@ -26,29 +26,9 @@
#include <linux/config.h>
#include <linux/proc_fs.h>
#include <linux/types.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
* @shost: SCSI host pointer
......
......@@ -2379,7 +2379,6 @@ static int ibmmca_proc_info(struct Scsi_Host *shpnt, char *buffer, char **start,
{
int len = 0;
int i, id, lun, host_index;
struct Scsi_Host *shpnt;
unsigned long flags;
int max_pun;
......@@ -2452,11 +2451,6 @@ static int ibmmca_proc_info(struct Scsi_Host *shpnt, char *buffer, char **start,
return len;
}
static void ibmmca_scsi_setup(char *str, int *ints)
{
internal_ibmmca_scsi_setup(str, ints);
}
static int option_setup(char *str)
{
int ints[IM_MAX_HOSTS];
......
......@@ -13,7 +13,6 @@
/* Interfaces to the midlevel Linux SCSI driver */
static int ibmmca_detect (Scsi_Host_Template *);
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_abort (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 )
* are guaranteed to be < 4G.
*/
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;
} 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");
return ips_abort_init(ha, index);
}
......
......@@ -76,6 +76,7 @@ static struct parisc_driver lasi700_driver = {
.name = "Lasi SCSI",
.id_table = lasi700_scsi_tbl,
.probe = lasi700_driver_callback,
.remove = __devexit_p(lasi700_driver_remove),
};
static int __init
......@@ -97,12 +98,6 @@ lasi700_driver_callback(struct parisc_device *dev)
}
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;
dma_set_mask(&dev->dev, 0xffffffffUL);
hostdata->base = base;
......@@ -122,7 +117,7 @@ lasi700_driver_callback(struct parisc_device *dev)
host = NCR_700_detect(&lasi700_template, hostdata);
if (!host)
goto out_release_mem_region;
goto out_kfree;
host->irq = dev->irq;
if (request_irq(dev->irq, NCR_700_intr, SA_SHIRQ,
......@@ -132,33 +127,33 @@ lasi700_driver_callback(struct parisc_device *dev)
goto out_put_host;
}
dev_set_drvdata(&dev->dev, host);
scsi_add_host(host, &dev->dev);
return 0;
out_put_host:
scsi_host_put(host);
out_release_mem_region:
release_mem_region(base, 64);
out_kfree:
kfree(hostdata);
return 1;
return -ENODEV;
}
#if 0
static int
lasi700_release(struct Scsi_Host *host)
static int __exit
lasi700_driver_remove(struct parisc_device *dev)
{
struct D700_Host_Parameters *hostdata =
(struct D700_Host_Parameters *)host->hostdata[0];
struct Scsi_Host *host = dev_get_drvdata(&dev->dev);
struct NCR_700_Host_Parameters *hostdata =
(struct NCR_700_Host_Parameters *)host->hostdata[0];
scsi_remove_host(host);
NCR_700_release(host);
kfree(hostdata);
free_irq(host->irq, host);
release_mem_region(host->base, 64);
unregister_parisc_driver(&lasi700_driver);
return 1;
kfree(hostdata);
return 0;
}
#endif
static int __init
lasi700_init(void)
......@@ -166,4 +161,12 @@ lasi700_init(void)
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_exit(lasi700_exit);
......@@ -25,9 +25,8 @@
#ifndef _LASI700_H
#define _LASI700_H
static int lasi700_detect(Scsi_Host_Template *);
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_700_SVERSION 0x071
......
......@@ -40,6 +40,7 @@
#include <linux/module.h>
#include <linux/list.h>
#include <linux/interrupt.h>
#include <linux/pci.h>
#include <scsi/scsicam.h>
#include "scsi.h"
......
This diff is collapsed.
......@@ -42,6 +42,79 @@
#ifndef 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"
/*==========================================================
**
** 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 */
......@@ -283,7 +283,6 @@ static const char *nsp32_info(struct Scsi_Host *);
static int nsp32_eh_abort(Scsi_Cmnd *);
static int nsp32_eh_bus_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 __devinit nsp32_probe(struct pci_dev *, const struct pci_device_id *);
static void __devexit nsp32_remove(struct pci_dev *);
......@@ -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)
{
nsp32_hw_data *data = (nsp32_hw_data *)SCpnt->device->host->hostdata;
......
......@@ -63,6 +63,7 @@ const char * osst_version = "0.99.0";
#include "scsi.h"
#include "hosts.h"
#include <scsi/scsi_driver.h>
#include <scsi/scsi_ioctl.h>
#define ST_KILOBYTE 1024
......
......@@ -139,7 +139,7 @@ struct scsi_request *scsi_allocate_request(struct scsi_device *sdev)
sreq->sr_device = sdev;
sreq->sr_host = sdev->host;
sreq->sr_magic = SCSI_REQ_MAGIC;
sreq->sr_data_direction = SCSI_DATA_UNKNOWN;
sreq->sr_data_direction = DMA_BIDIRECTIONAL;
}
return sreq;
......
......@@ -24,54 +24,6 @@
#include <scsi/scsi_tcq.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.
*/
......@@ -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,
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
* 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)
static int scsi_request_sense(struct scsi_cmnd *scmd)
{
static unsigned char generic_sense[6] =
{REQUEST_SENSE, 0, 0, 0, 254, 0};
{REQUEST_SENSE, 0, 0, 0, 252, 0};
unsigned char *scsi_result;
int saved_result;
int rtn;
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)) {
......@@ -555,14 +555,14 @@ static int scsi_request_sense(struct scsi_cmnd *scmd)
* address (db). 0 is not a valid sense code.
*/
memset(scmd->sense_buffer, 0, sizeof(scmd->sense_buffer));
memset(scsi_result, 0, 254);
memset(scsi_result, 0, 252);
saved_result = scmd->result;
scmd->request_buffer = scsi_result;
scmd->request_bufflen = 254;
scmd->request_bufflen = 252;
scmd->use_sg = 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;
rtn = scsi_send_eh_cmnd(scmd, SENSE_TIMEOUT);
......@@ -742,7 +742,7 @@ static int scsi_eh_tur(struct scsi_cmnd *scmd)
scmd->use_sg = 0;
scmd->cmd_len = COMMAND_SIZE(scmd->cmnd[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);
......@@ -1338,7 +1338,7 @@ static void scsi_eh_lock_door(struct scsi_device *sdev)
if (unlikely(!sreq)) {
printk(KERN_ERR "%s: request allocate failed,"
"prevent media removal cmd not sent", __FUNCTION__);
"prevent media removal cmd not sent\n", __FUNCTION__);
return;
}
......@@ -1348,7 +1348,7 @@ static void scsi_eh_lock_door(struct scsi_device *sdev)
sreq->sr_cmnd[3] = 0;
sreq->sr_cmnd[4] = SCSI_REMOVAL_PREVENT;
sreq->sr_cmnd[5] = 0;
sreq->sr_data_direction = SCSI_DATA_NONE;
sreq->sr_data_direction = DMA_NONE;
sreq->sr_bufflen = 0;
sreq->sr_buffer = NULL;
sreq->sr_allowed = 5;
......@@ -1723,7 +1723,7 @@ scsi_reset_provider(struct scsi_device *dev, int flag)
scmd->cmd_len = 0;
scmd->sc_data_direction = SCSI_DATA_UNKNOWN;
scmd->sc_data_direction = DMA_BIDIRECTIONAL;
scmd->sc_request = NULL;
scmd->sc_magic = SCSI_CMND_MAGIC;
......
......@@ -104,7 +104,7 @@ static int ioctl_internal_command(struct scsi_device *sdev, char *cmd,
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_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,
return -ENOMEM;
memset(buf, 0, buf_needed);
if (inlen == 0) {
data_direction = SCSI_DATA_READ;
data_direction = DMA_FROM_DEVICE;
} else if (outlen == 0 ) {
data_direction = SCSI_DATA_WRITE;
data_direction = DMA_TO_DEVICE;
} else {
/*
* Can this ever happen?
*/
data_direction = SCSI_DATA_UNKNOWN;
data_direction = DMA_BIDIRECTIONAL;
}
} else {
buf = NULL;
data_direction = SCSI_DATA_NONE;
data_direction = DMA_NONE;
}
/*
......@@ -322,7 +322,7 @@ int scsi_ioctl_send_command(struct scsi_device *sdev,
}
sreq = scsi_allocate_request(sdev);
if (sreq) {
if (!sreq) {
result = -EINTR;
goto error;
}
......
......@@ -18,6 +18,7 @@
#include "scsi.h"
#include "hosts.h"
#include <scsi/scsi_driver.h>
#include "scsi_priv.h"
#include "scsi_logging.h"
......@@ -1094,14 +1095,17 @@ static inline int scsi_host_queue_ready(struct request_queue *q,
return 0;
}
}
if (!list_empty(&sdev->starved_entry))
return 0;
if ((shost->can_queue > 0 && shost->host_busy >= shost->can_queue) ||
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;
}
/* 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;
}
......@@ -1128,6 +1132,7 @@ static void scsi_request_fn(struct request_queue *q)
* the host is no longer able to accept any more requests.
*/
while (!blk_queue_plugged(q)) {
int rtn;
/*
* get next queueable request. We do this early to make sure
* that the request is fully prepared even if we cannot
......@@ -1181,8 +1186,17 @@ static void scsi_request_fn(struct request_queue *q)
/*
* Dispatch the command to the low-level driver.
*/
scsi_dispatch_cmd(cmd);
rtn = scsi_dispatch_cmd(cmd);
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;
......@@ -1203,6 +1217,8 @@ static void scsi_request_fn(struct request_queue *q)
blk_queue_end_tag(q, req);
__elv_add_request(q, req, 0, 0);
sdev->device_busy--;
if(sdev->device_busy == 0)
blk_plug_device(q);
}
u64 scsi_calculate_bounce_limit(struct Scsi_Host *shost)
......@@ -1336,3 +1352,127 @@ void scsi_exit_queue(void)
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 @@
#include "scsi.h"
#include "hosts.h"
#include <scsi/scsi_driver.h>
#include "scsi_priv.h"
#include "scsi_logging.h"
......@@ -116,7 +117,7 @@ static void scsi_unlock_floptical(struct scsi_request *sreq,
scsi_cmd[4] = 0x2a; /* size */
scsi_cmd[5] = 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);
}
......@@ -333,7 +334,7 @@ static void scsi_probe_lun(struct scsi_request *sreq, char *inq_result,
scsi_cmd[0] = INQUIRY;
scsi_cmd[4] = 36; /* issue conservative alloc_length */
sreq->sr_cmd_len = 0;
sreq->sr_data_direction = SCSI_DATA_READ;
sreq->sr_data_direction = DMA_FROM_DEVICE;
memset(inq_result, 0, 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,
scsi_cmd[0] = INQUIRY;
scsi_cmd[4] = (unsigned char) possible_inq_resp_len;
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.
*/
......@@ -940,7 +941,7 @@ static int scsi_report_lun_scan(struct scsi_device *sdev, int bflags)
scsi_cmd[10] = 0; /* reserved */
scsi_cmd[11] = 0; /* control */
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
......
......@@ -19,6 +19,7 @@
#include <asm/dma.h>
#include "scsi.h"
#include <scsi/scsi_driver.h>
#include <scsi/scsi_ioctl.h>
#include "hosts.h"
#include "scsi_logging.h"
......@@ -86,6 +87,9 @@ EXPORT_SYMBOL(scsi_add_device);
EXPORT_SYMBOL(scsi_remove_device);
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.
*/
......
......@@ -194,20 +194,14 @@ sdev_rd_attr (model, "%.16s\n");
sdev_rd_attr (rev, "%.4s\n");
sdev_rw_attr_bit (online);
static ssize_t
show_rescan_field (struct device *dev, char *buf)
{
return 0;
}
static ssize_t
store_rescan_field (struct device *dev, const char *buf, size_t count)
{
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 */
struct device_attribute *scsi_sysfs_sdev_attrs[] = {
......@@ -388,30 +382,36 @@ void scsi_sysfs_remove_host(struct Scsi_Host *shost)
*
* returns zero if successful or error if not
**/
int scsi_sysfs_modify_shost_attribute(struct class_device_attribute ***class_attrs,
struct class_device_attribute *attr)
int scsi_sysfs_modify_shost_attribute(
struct class_device_attribute ***class_attrs,
struct class_device_attribute *attr)
{
int modify = 0;
int modify = -1;
int num_attrs;
if(*class_attrs == NULL)
*class_attrs = scsi_sysfs_shost_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;
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 */
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)
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)
kfree(*class_attrs);
*class_attrs = tmp_attrs;
}
if(modify) {
if(modify >= 0) {
/* spare the caller from having to copy things it's
* not interested in */
struct class_device_attribute *old_attr =
......@@ -444,27 +444,32 @@ EXPORT_SYMBOL(scsi_sysfs_modify_shost_attribute);
int scsi_sysfs_modify_sdev_attribute(struct device_attribute ***dev_attrs,
struct device_attribute *attr)
{
int modify = 0;
int modify = -1;
int num_attrs;
if(*dev_attrs == NULL)
*dev_attrs = scsi_sysfs_sdev_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;
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 */
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)
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)
kfree(*dev_attrs);
*dev_attrs = tmp_attrs;
}
if(modify) {
if(modify >= 0) {
/* spare the caller from having to copy things it's
* not interested in */
struct device_attribute *old_attr =
......
......@@ -49,6 +49,8 @@
#include "scsi.h"
#include "hosts.h"
#include <scsi/scsi_driver.h>
#include <scsi/scsi_ioctl.h>
#include <scsi/scsicam.h>
......@@ -161,11 +163,11 @@ static int sd_init_command(struct scsi_cmnd * SCpnt)
memcpy(SCpnt->cmnd, rq->cmd, sizeof(SCpnt->cmnd));
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)
SCpnt->sc_data_direction = SCSI_DATA_READ;
SCpnt->sc_data_direction = DMA_FROM_DEVICE;
else
SCpnt->sc_data_direction = SCSI_DATA_NONE;
SCpnt->sc_data_direction = DMA_NONE;
this_count = rq->data_len;
if (rq->timeout)
......@@ -251,10 +253,10 @@ static int sd_init_command(struct scsi_cmnd * SCpnt)
return 0;
}
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) {
SCpnt->cmnd[0] = READ_6;
SCpnt->sc_data_direction = SCSI_DATA_READ;
SCpnt->sc_data_direction = DMA_FROM_DEVICE;
} else {
printk(KERN_ERR "sd: Unknown command %lx\n",
SCpnt->request->flags);
......@@ -790,7 +792,7 @@ sd_spinup_disk(struct scsi_disk *sdkp, char *diskname,
SRpnt->sr_cmd_len = 0;
SRpnt->sr_sense_buffer[0] = 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,
0/*512*/, SD_TIMEOUT, SD_MAX_RETRIES);
......@@ -850,7 +852,7 @@ sd_spinup_disk(struct scsi_disk *sdkp, char *diskname,
SRpnt->sr_sense_buffer[0] = 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, 0/*512*/,
SD_TIMEOUT, SD_MAX_RETRIES);
......@@ -915,7 +917,7 @@ sd_read_capacity(struct scsi_disk *sdkp, char *diskname,
SRpnt->sr_cmd_len = 0;
SRpnt->sr_sense_buffer[0] = 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,
longrc ? 12 : 8, SD_TIMEOUT, SD_MAX_RETRIES);
......@@ -1062,40 +1064,12 @@ sd_read_capacity(struct scsi_disk *sdkp, char *diskname,
}
/* called with buffer of length 512 */
static int
static inline int
sd_do_mode_sense(struct scsi_request *SRpnt, int dbd, int modepage,
unsigned char *buffer, int len) {
unsigned char cmd[12];
memset((void *) &cmd[0], 0, 12);
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;
unsigned char *buffer, int len, struct scsi_mode_data *data)
{
return __scsi_mode_sense(SRpnt, dbd, modepage, buffer, len,
SD_TIMEOUT, SD_MAX_RETRIES, data);
}
/*
......@@ -1106,33 +1080,34 @@ static void
sd_read_write_protect_flag(struct scsi_disk *sdkp, char *diskname,
struct scsi_request *SRpnt, unsigned char *buffer) {
int res;
struct scsi_mode_data data;
/*
* First attempt: ask for all pages (0x3F), but only 4 bytes.
* We have to start carefully: some devices hang if we ask
* 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
* 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.
*/
if (res)
res = sd_do_mode_sense(SRpnt, 0, 0, buffer, 4);
if (!scsi_status_is_good(res))
res = sd_do_mode_sense(SRpnt, 0, 0, buffer, 4, &data);
/*
* Third attempt: ask 255 bytes, as we did earlier.
*/
if (res)
res = sd_do_mode_sense(SRpnt, 0, 0x3F, buffer, 255);
if (!scsi_status_is_good(res))
res = sd_do_mode_sense(SRpnt, 0, 0x3F, buffer, 255, &data);
if (res) {
if (!scsi_status_is_good(res)) {
printk(KERN_WARNING
"%s: test WP failed, assume Write Enabled\n", diskname);
} 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,
sdkp->write_prot ? "on" : "off");
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,
struct scsi_request *SRpnt, unsigned char *buffer) {
int len = 0, res;
const int dbd = 0x08; /* DBD */
const int dbd = 0; /* DBD */
const int modepage = 0x08; /* current values, cache page */
struct scsi_mode_data data;
/* 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 */
len = buffer[0] + 1;
len = data.length;
if (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[] = {
"write through", "none", "write back",
"write back, no read (daft)"
};
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->RCD = ((buffer[offset + 2] & 0x01) != 0);
sdkp->WCE = ((buffer[offset] & 0x04) != 0);
sdkp->RCD = ((buffer[offset] & 0x01) != 0);
ct = sdkp->RCD + 2*sdkp->WCE;
printk(KERN_NOTICE "SCSI device %s: drive cache: %s\n",
diskname, types[ct]);
} else {
if (res == 0 ||
(status_byte(res) == CHECK_CONDITION
&& (SRpnt->sr_sense_buffer[0] & 0x70) == 0x70
if ((SRpnt->sr_sense_buffer[0] & 0x70) == 0x70
&& (SRpnt->sr_sense_buffer[2] & 0x0f) == ILLEGAL_REQUEST
/* ASC 0x24 ASCQ 0x00: Invalid field in CDB */
&& 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",
diskname);
} else {
......@@ -1417,7 +1394,7 @@ static void sd_shutdown(struct device *dev)
return;
}
sreq->sr_data_direction = SCSI_DATA_NONE;
sreq->sr_data_direction = DMA_NONE;
for (retries = 3; retries > 0; --retries) {
unsigned char cmd[10] = { 0 };
......
......@@ -266,20 +266,6 @@ MODULE_LICENSE("GPL");
#define WRITE_CONTROL(d) { isa_writeb((d), st0x_cr_sr); }
#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
static unsigned int seagate_bases[] = {
0xc8000, 0xca000, 0xcc000,
......
......@@ -10,7 +10,6 @@
#define SEAGATE_H
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_abort(Scsi_Cmnd *);
......
......@@ -64,6 +64,7 @@ static int sg_version_num = 30529; /* 2 digits for each component */
#include <linux/blk.h>
#include "scsi.h"
#include "hosts.h"
#include <scsi/scsi_driver.h>
#include <scsi/scsi_ioctl.h>
#include <scsi/sg.h>
......
......@@ -48,6 +48,8 @@
#include "scsi.h"
#include "hosts.h"
#include <scsi/scsi_driver.h>
#include <scsi/scsi_ioctl.h> /* For the door lock/unlock commands */
#include "scsi_logging.h"
......@@ -660,9 +662,9 @@ static void get_sectorsize(struct scsi_cd *cd)
static void get_capabilities(struct scsi_cd *cd)
{
struct cdrom_generic_command cgc;
unsigned char *buffer;
int rc, n;
struct scsi_mode_data data;
static char *loadmech[] =
{
......@@ -681,18 +683,10 @@ static void get_capabilities(struct scsi_cd *cd)
printk(KERN_ERR "sr: out of memory.\n");
return;
}
memset(&cgc, 0, sizeof(struct cdrom_generic_command));
cgc.cmd[0] = MODE_SENSE;
cgc.cmd[2] = 0x2a;
cgc.cmd[4] = 128;
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) {
rc = scsi_mode_sense(cd->device, 0, 0x2a, buffer, 128,
SR_TIMEOUT, 3, &data);
if (!scsi_status_is_good(rc)) {
/* failed, drive doesn't have capabilities mode page */
cd->cdi.speed = 1;
cd->cdi.mask |= (CDC_CD_R | CDC_CD_RW | CDC_DVD_R |
......@@ -702,7 +696,7 @@ static void get_capabilities(struct scsi_cd *cd)
printk("%s: scsi-1 drive\n", cd->cdi.name);
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->readcd_known = 1;
cd->readcd_cdda = buffer[n + 5] & 0x01;
......
......@@ -58,6 +58,8 @@ static char *verstr = "20030622";
#include "scsi.h"
#include "hosts.h"
#include <scsi/scsi_driver.h>
#include <scsi/scsi_ioctl.h>
#define ST_KILOBYTE 1024
......
......@@ -25,7 +25,6 @@
static int sym53c416_detect(Scsi_Host_Template *);
static const char *sym53c416_info(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_abort(Scsi_Cmnd *);
static int sym53c416_host_reset(Scsi_Cmnd *);
......
......@@ -295,12 +295,8 @@ struct host_data {
#ifndef SYM_LINUX_DYNAMIC_DMA_MAPPING
typedef u_long bus_addr_t;
#else
#if SYM_CONF_DMA_ADDRESSING_MODE > 0
typedef dma64_addr_t bus_addr_t;
#else
typedef dma_addr_t bus_addr_t;
#endif
#endif
/*
* Used by the eh thread to wait for command completion.
......@@ -1863,7 +1859,7 @@ static int sym_setup_bus_dma_mask(hcb_p np)
#if SYM_CONF_DMA_ADDRESSING_MODE == 1
#define PciDmaMask 0xffffffffff
#elif SYM_CONF_DMA_ADDRESSING_MODE == 2
#define PciDmaMask 0xffffffffffffffff
#define PciDmaMask 0xffffffffffffffffULL
#endif
if (np->features & FE_DAC) {
if (!pci_set_dma_mask(np->s.device, PciDmaMask)) {
......@@ -2753,14 +2749,6 @@ if (sym53c8xx)
/* This one is guaranteed by AC to do nothing :-) */
if (pci_enable_device(pcidev))
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->host_id = SYM_SETUP_HOST_ID;
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