aboutsummaryrefslogtreecommitdiff
path: root/drivers/scsi
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/3w-9xxx.c9
-rw-r--r--drivers/scsi/3w-xxxx.c3
-rw-r--r--drivers/scsi/aacraid/linit.c3
-rw-r--r--drivers/scsi/aha152x.c4
-rw-r--r--drivers/scsi/aic94xx/aic94xx_sds.c12
-rw-r--r--drivers/scsi/aic94xx/aic94xx_sds.h4
-rw-r--r--drivers/scsi/aic94xx/aic94xx_seq.c7
-rw-r--r--drivers/scsi/arm/Kconfig2
-rw-r--r--drivers/scsi/arm/acornscsi-io.S15
-rw-r--r--drivers/scsi/arm/acornscsi.c426
-rw-r--r--drivers/scsi/arm/acornscsi.h9
-rw-r--r--drivers/scsi/atp870u.c2
-rw-r--r--drivers/scsi/ch.c4
-rw-r--r--drivers/scsi/dpt/dptsig.h3
-rw-r--r--drivers/scsi/dpt_i2o.c5
-rw-r--r--drivers/scsi/esp_scsi.c22
-rw-r--r--drivers/scsi/gdth.c3
-rw-r--r--drivers/scsi/hosts.c9
-rw-r--r--drivers/scsi/hptiop.c12
-rw-r--r--drivers/scsi/ibmvscsi/ibmvscsi.c2
-rw-r--r--drivers/scsi/ibmvscsi/viosrp.h3
-rw-r--r--drivers/scsi/ipr.c6
-rw-r--r--drivers/scsi/megaraid.c5
-rw-r--r--drivers/scsi/megaraid/megaraid_mm.c2
-rw-r--r--drivers/scsi/megaraid/megaraid_sas.c2
-rw-r--r--drivers/scsi/osst.c15
-rw-r--r--drivers/scsi/qla1280.c2
-rw-r--r--drivers/scsi/qla2xxx/qla_attr.c13
-rw-r--r--drivers/scsi/qla2xxx/qla_def.h2
-rw-r--r--drivers/scsi/qla2xxx/qla_gbl.h3
-rw-r--r--drivers/scsi/qla2xxx/qla_inline.h4
-rw-r--r--drivers/scsi/qla2xxx/qla_isr.c63
-rw-r--r--drivers/scsi/qla2xxx/qla_mbx.c12
-rw-r--r--drivers/scsi/qla2xxx/qla_mid.c19
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c30
-rw-r--r--drivers/scsi/qla2xxx/qla_version.h2
-rw-r--r--drivers/scsi/scsi_lib.c9
-rw-r--r--drivers/scsi/scsi_sysfs.c7
-rw-r--r--drivers/scsi/scsi_tgt_if.c2
-rw-r--r--drivers/scsi/ses.c2
-rw-r--r--drivers/scsi/sg.c60
-rw-r--r--drivers/scsi/sr.c23
-rw-r--r--drivers/scsi/st.c11
43 files changed, 425 insertions, 428 deletions
diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c
index b31faeccb9c..7045511f9ad 100644
--- a/drivers/scsi/3w-9xxx.c
+++ b/drivers/scsi/3w-9xxx.c
@@ -84,6 +84,7 @@
#include <linux/pci.h>
#include <linux/time.h>
#include <linux/mutex.h>
+#include <linux/smp_lock.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/uaccess.h>
@@ -862,11 +863,13 @@ out:
} /* End twa_chrdev_ioctl() */
/* This function handles open for the character device */
+/* NOTE that this function will race with remove. */
static int twa_chrdev_open(struct inode *inode, struct file *file)
{
unsigned int minor_number;
int retval = TW_IOCTL_ERROR_OS_ENODEV;
+ cycle_kernel_lock();
minor_number = iminor(inode);
if (minor_number >= twa_device_extension_count)
goto out;
@@ -1278,7 +1281,7 @@ static irqreturn_t twa_interrupt(int irq, void *dev_instance)
error = 0;
/* Check for command packet errors */
if (full_command_packet->command.newcommand.status != 0) {
- if (tw_dev->srb[request_id] != 0) {
+ if (tw_dev->srb[request_id] != NULL) {
error = twa_fill_sense(tw_dev, request_id, 1, 1);
} else {
/* Skip ioctl error prints */
@@ -1290,7 +1293,7 @@ static irqreturn_t twa_interrupt(int irq, void *dev_instance)
/* Check for correct state */
if (tw_dev->state[request_id] != TW_S_POSTED) {
- if (tw_dev->srb[request_id] != 0) {
+ if (tw_dev->srb[request_id] != NULL) {
TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1a, "Received a request id that wasn't posted");
TW_CLEAR_ALL_INTERRUPTS(tw_dev);
goto twa_interrupt_bail;
@@ -1298,7 +1301,7 @@ static irqreturn_t twa_interrupt(int irq, void *dev_instance)
}
/* Check for internal command completion */
- if (tw_dev->srb[request_id] == 0) {
+ if (tw_dev->srb[request_id] == NULL) {
if (request_id != tw_dev->chrdev_request_id) {
if (twa_aen_complete(tw_dev, request_id))
TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1b, "Error completing AEN during attention interrupt");
diff --git a/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c
index 8c22329aa85..a0537f09aa2 100644
--- a/drivers/scsi/3w-xxxx.c
+++ b/drivers/scsi/3w-xxxx.c
@@ -198,6 +198,7 @@
#include <linux/module.h>
#include <linux/reboot.h>
+#include <linux/smp_lock.h>
#include <linux/spinlock.h>
#include <linux/interrupt.h>
#include <linux/moduleparam.h>
@@ -1027,10 +1028,12 @@ out:
} /* End tw_chrdev_ioctl() */
/* This function handles open for the character device */
+/* NOTE that this function races with remove. */
static int tw_chrdev_open(struct inode *inode, struct file *file)
{
unsigned int minor_number;
+ cycle_kernel_lock();
dprintk(KERN_WARNING "3w-xxxx: tw_ioctl_open()\n");
minor_number = iminor(inode);
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
index 1f7c83607f8..68c140e8267 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -38,6 +38,7 @@
#include <linux/moduleparam.h>
#include <linux/pci.h>
#include <linux/slab.h>
+#include <linux/smp_lock.h>
#include <linux/spinlock.h>
#include <linux/syscalls.h>
#include <linux/delay.h>
@@ -667,6 +668,7 @@ static int aac_cfg_open(struct inode *inode, struct file *file)
unsigned minor_number = iminor(inode);
int err = -ENODEV;
+ lock_kernel(); /* BKL pushdown: nothing else protects this list */
list_for_each_entry(aac, &aac_devices, entry) {
if (aac->id == minor_number) {
file->private_data = aac;
@@ -674,6 +676,7 @@ static int aac_cfg_open(struct inode *inode, struct file *file)
break;
}
}
+ unlock_kernel();
return err;
}
diff --git a/drivers/scsi/aha152x.c b/drivers/scsi/aha152x.c
index 1dca1775f4b..0899cb61e3d 100644
--- a/drivers/scsi/aha152x.c
+++ b/drivers/scsi/aha152x.c
@@ -3582,7 +3582,7 @@ static int checksetup(struct aha152x_setup *setup)
if (i == ARRAY_SIZE(ports))
return 0;
- if ( request_region(setup->io_port, IO_RANGE, "aha152x")==0 ) {
+ if (!request_region(setup->io_port, IO_RANGE, "aha152x")) {
printk(KERN_ERR "aha152x: io port 0x%x busy.\n", setup->io_port);
return 0;
}
@@ -3842,7 +3842,7 @@ static int __init aha152x_init(void)
if ((setup_count == 1) && (setup[0].io_port == ports[i]))
continue;
- if ( request_region(ports[i], IO_RANGE, "aha152x")==0 ) {
+ if (!request_region(ports[i], IO_RANGE, "aha152x")) {
printk(KERN_ERR "aha152x: io port 0x%x busy.\n", ports[i]);
continue;
}
diff --git a/drivers/scsi/aic94xx/aic94xx_sds.c b/drivers/scsi/aic94xx/aic94xx_sds.c
index 4446e3d584d..8630a75b287 100644
--- a/drivers/scsi/aic94xx/aic94xx_sds.c
+++ b/drivers/scsi/aic94xx/aic94xx_sds.c
@@ -1093,9 +1093,9 @@ out:
* @bytes_to_verify: total bytes to verify
*/
int asd_verify_flash_seg(struct asd_ha_struct *asd_ha,
- void *src, u32 dest_offset, u32 bytes_to_verify)
+ const void *src, u32 dest_offset, u32 bytes_to_verify)
{
- u8 *src_buf;
+ const u8 *src_buf;
u8 flash_char;
int err;
u32 nv_offset, reg, i;
@@ -1105,7 +1105,7 @@ int asd_verify_flash_seg(struct asd_ha_struct *asd_ha,
err = FLASH_OK;
nv_offset = dest_offset;
- src_buf = (u8 *)src;
+ src_buf = (const u8 *)src;
for (i = 0; i < bytes_to_verify; i++) {
flash_char = asd_read_reg_byte(asd_ha, reg + nv_offset + i);
if (flash_char != src_buf[i]) {
@@ -1124,9 +1124,9 @@ int asd_verify_flash_seg(struct asd_ha_struct *asd_ha,
* @bytes_to_write: total bytes to write
*/
int asd_write_flash_seg(struct asd_ha_struct *asd_ha,
- void *src, u32 dest_offset, u32 bytes_to_write)
+ const void *src, u32 dest_offset, u32 bytes_to_write)
{
- u8 *src_buf;
+ const u8 *src_buf;
u32 nv_offset, reg, i;
int err;
@@ -1153,7 +1153,7 @@ int asd_write_flash_seg(struct asd_ha_struct *asd_ha,
return err;
}
- src_buf = (u8 *)src;
+ src_buf = (const u8 *)src;
for (i = 0; i < bytes_to_write; i++) {
/* Setup program command sequence */
switch (asd_ha->hw_prof.flash.method) {
diff --git a/drivers/scsi/aic94xx/aic94xx_sds.h b/drivers/scsi/aic94xx/aic94xx_sds.h
index bb9795a04dc..a06dc0114b8 100644
--- a/drivers/scsi/aic94xx/aic94xx_sds.h
+++ b/drivers/scsi/aic94xx/aic94xx_sds.h
@@ -110,9 +110,9 @@ struct bios_file_header {
};
int asd_verify_flash_seg(struct asd_ha_struct *asd_ha,
- void *src, u32 dest_offset, u32 bytes_to_verify);
+ const void *src, u32 dest_offset, u32 bytes_to_verify);
int asd_write_flash_seg(struct asd_ha_struct *asd_ha,
- void *src, u32 dest_offset, u32 bytes_to_write);
+ const void *src, u32 dest_offset, u32 bytes_to_write);
int asd_chk_write_status(struct asd_ha_struct *asd_ha,
u32 sector_addr, u8 erase_flag);
int asd_check_flash_type(struct asd_ha_struct *asd_ha);
diff --git a/drivers/scsi/aic94xx/aic94xx_seq.c b/drivers/scsi/aic94xx/aic94xx_seq.c
index f4272ac4c68..8f98e33155e 100644
--- a/drivers/scsi/aic94xx/aic94xx_seq.c
+++ b/drivers/scsi/aic94xx/aic94xx_seq.c
@@ -46,7 +46,7 @@
static const struct firmware *sequencer_fw;
static u16 cseq_vecs[CSEQ_NUM_VECS], lseq_vecs[LSEQ_NUM_VECS], mode2_task,
cseq_idle_loop, lseq_idle_loop;
-static u8 *cseq_code, *lseq_code;
+static const u8 *cseq_code, *lseq_code;
static u32 cseq_code_size, lseq_code_size;
static u16 first_scb_site_no = 0xFFFF;
@@ -1235,7 +1235,8 @@ int asd_release_firmware(void)
static int asd_request_firmware(struct asd_ha_struct *asd_ha)
{
int err, i;
- struct sequencer_file_header header, *hdr_ptr;
+ struct sequencer_file_header header;
+ const struct sequencer_file_header *hdr_ptr;
u32 csum = 0;
u16 *ptr_cseq_vecs, *ptr_lseq_vecs;
@@ -1249,7 +1250,7 @@ static int asd_request_firmware(struct asd_ha_struct *asd_ha)
if (err)
return err;
- hdr_ptr = (struct sequencer_file_header *)sequencer_fw->data;
+ hdr_ptr = (const struct sequencer_file_header *)sequencer_fw->data;
header.csum = le32_to_cpu(hdr_ptr->csum);
header.major = le32_to_cpu(hdr_ptr->major);
diff --git a/drivers/scsi/arm/Kconfig b/drivers/scsi/arm/Kconfig
index 7236143941f..a8587f1f5e7 100644
--- a/drivers/scsi/arm/Kconfig
+++ b/drivers/scsi/arm/Kconfig
@@ -3,7 +3,7 @@
#
config SCSI_ACORNSCSI_3
tristate "Acorn SCSI card (aka30) support"
- depends on ARCH_ACORN && SCSI && BROKEN
+ depends on ARCH_ACORN && SCSI
select SCSI_SPI_ATTRS
help
This enables support for the Acorn SCSI card (aka30). If you have an
diff --git a/drivers/scsi/arm/acornscsi-io.S b/drivers/scsi/arm/acornscsi-io.S
index 93467e6ac92..5cebe310526 100644
--- a/drivers/scsi/arm/acornscsi-io.S
+++ b/drivers/scsi/arm/acornscsi-io.S
@@ -10,17 +10,10 @@
#include <asm/assembler.h>
#include <asm/hardware.h>
-#if (IO_BASE == (PCIO_BASE & 0xff000000))
-#define ADDR(off,reg) \
- tst off, $0x80000000 ;\
- mov reg, $IO_BASE ;\
- orreq reg, reg, $(PCIO_BASE & 0x00ff0000)
-#else
-#define ADDR(off,reg) \
- tst off, $0x80000000 ;\
- movne reg, $IO_BASE ;\
- moveq reg, $(PCIO_BASE & 0xff000000) ;\
- orreq reg, reg, $(PCIO_BASE & 0x00ff0000)
+#if defined(__APCS_32__)
+#define LOADREGS(t,r,l...) ldm##t r, l
+#elif defined(__APCS_26__)
+#define LOADREGS(t,r,l...) ldm##t r, l##^
#endif
@ Purpose: transfer a block of data from the acorn scsi card to memory
diff --git a/drivers/scsi/arm/acornscsi.c b/drivers/scsi/arm/acornscsi.c
index 8e53f02cc31..918ccf81875 100644
--- a/drivers/scsi/arm/acornscsi.c
+++ b/drivers/scsi/arm/acornscsi.c
@@ -123,12 +123,6 @@
#define DBG(cmd,xxx...) xxx
#endif
-#ifndef STRINGIFY
-#define STRINGIFY(x) #x
-#endif
-#define STRx(x) STRINGIFY(x)
-#define NO_WRITE_STR STRx(NO_WRITE)
-
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/string.h>
@@ -141,9 +135,10 @@
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/bitops.h>
+#include <linux/stringify.h>
+#include <linux/io.h>
#include <asm/system.h>
-#include <asm/io.h>
#include <asm/ecard.h>
#include "../scsi.h"
@@ -203,44 +198,46 @@ static void acornscsi_abortcmd(AS_Host *host, unsigned char tag);
* Miscellaneous
*/
-static inline void
-sbic_arm_write(unsigned int io_port, int reg, int value)
+/* Offsets from MEMC base */
+#define SBIC_REGIDX 0x2000
+#define SBIC_REGVAL 0x2004
+#define DMAC_OFFSET 0x3000
+
+/* Offsets from FAST IOC base */
+#define INT_REG 0x2000
+#define PAGE_REG 0x3000
+
+static inline void sbic_arm_write(AS_Host *host, unsigned int reg, unsigned int value)
{
- __raw_writeb(reg, io_port);
- __raw_writeb(value, io_port + 4);
+ writeb(reg, host->base + SBIC_REGIDX);
+ writeb(value, host->base + SBIC_REGVAL);
}
-#define sbic_arm_writenext(io,val) \
- __raw_writeb((val), (io) + 4)
-
-static inline
-int sbic_arm_read(unsigned int io_port, int reg)
+static inline int sbic_arm_read(AS_Host *host, unsigned int reg)
{
if(reg == SBIC_ASR)
- return __raw_readl(io_port) & 255;
- __raw_writeb(reg, io_port);
- return __raw_readl(io_port + 4) & 255;
+ return readl(host->base + SBIC_REGIDX) & 255;
+ writeb(reg, host->base + SBIC_REGIDX);
+ return readl(host->base + SBIC_REGVAL) & 255;
}
-#define sbic_arm_readnext(io) \
- __raw_readb((io) + 4)
+#define sbic_arm_writenext(host, val) writeb((val), (host)->base + SBIC_REGVAL)
+#define sbic_arm_readnext(host) readb((host)->base + SBIC_REGVAL)
#ifdef USE_DMAC
-#define dmac_read(io_port,reg) \
- inb((io_port) + (reg))
+#define dmac_read(host,reg) \
+ readb((host)->base + DMAC_OFFSET + ((reg) << 2))
-#define dmac_write(io_port,reg,value) \
- ({ outb((value), (io_port) + (reg)); })
+#define dmac_write(host,reg,value) \
+ ({ writeb((value), (host)->base + DMAC_OFFSET + ((reg) << 2)); })
-#define dmac_clearintr(io_port) \
- ({ outb(0, (io_port)); })
+#define dmac_clearintr(host) writeb(0, (host)->fast + INT_REG)
-static inline
-unsigned int dmac_address(unsigned int io_port)
+static inline unsigned int dmac_address(AS_Host *host)
{
- return dmac_read(io_port, DMAC_TXADRHI) << 16 |
- dmac_read(io_port, DMAC_TXADRMD) << 8 |
- dmac_read(io_port, DMAC_TXADRLO);
+ return dmac_read(host, DMAC_TXADRHI) << 16 |
+ dmac_read(host, DMAC_TXADRMD) << 8 |
+ dmac_read(host, DMAC_TXADRLO);
}
static
@@ -248,15 +245,15 @@ void acornscsi_dumpdma(AS_Host *host, char *where)
{
unsigned int mode, addr, len;
- mode = dmac_read(host->dma.io_port, DMAC_MODECON);
- addr = dmac_address(host->dma.io_port);
- len = dmac_read(host->dma.io_port, DMAC_TXCNTHI) << 8 |
- dmac_read(host->dma.io_port, DMAC_TXCNTLO);
+ mode = dmac_read(host, DMAC_MODECON);
+ addr = dmac_address(host);
+ len = dmac_read(host, DMAC_TXCNTHI) << 8 |
+ dmac_read(host, DMAC_TXCNTLO);
printk("scsi%d: %s: DMAC %02x @%06x+%04x msk %02x, ",
host->host->host_no, where,
mode, addr, (len + 1) & 0xffff,
- dmac_read(host->dma.io_port, DMAC_MASKREG));
+ dmac_read(host, DMAC_MASKREG));
printk("DMA @%06x, ", host->dma.start_addr);
printk("BH @%p +%04x, ", host->scsi.SCp.ptr,
@@ -272,9 +269,9 @@ unsigned long acornscsi_sbic_xfcount(AS_Host *host)
{
unsigned long length;
- length = sbic_arm_read(host->scsi.io_port, SBIC_TRANSCNTH) << 16;
- length |= sbic_arm_readnext(host->scsi.io_port) << 8;
- length |= sbic_arm_readnext(host->scsi.io_port);
+ length = sbic_arm_read(host, SBIC_TRANSCNTH) << 16;
+ length |= sbic_arm_readnext(host) << 8;
+ length |= sbic_arm_readnext(host);
return length;
}
@@ -285,7 +282,7 @@ acornscsi_sbic_wait(AS_Host *host, int stat_mask, int stat, int timeout, char *m
int asr;
do {
- asr = sbic_arm_read(host->scsi.io_port, SBIC_ASR);
+ asr = sbic_arm_read(host, SBIC_ASR);
if ((asr & stat_mask) == stat)
return 0;
@@ -304,7 +301,7 @@ int acornscsi_sbic_issuecmd(AS_Host *host, int command)
if (acornscsi_sbic_wait(host, ASR_CIP, 0, 1000, "issuing command"))
return -1;
- sbic_arm_write(host->scsi.io_port, SBIC_CMND, command);
+ sbic_arm_write(host, SBIC_CMND, command);
return 0;
}
@@ -331,20 +328,20 @@ void acornscsi_resetcard(AS_Host *host)
/* assert reset line */
host->card.page_reg = 0x80;
- outb(host->card.page_reg, host->card.io_page);
+ writeb(host->card.page_reg, host->fast + PAGE_REG);
/* wait 3 cs. SCSI standard says 25ms. */
acornscsi_csdelay(3);
host->card.page_reg = 0;
- outb(host->card.page_reg, host->card.io_page);
+ writeb(host->card.page_reg, host->fast + PAGE_REG);
/*
* Should get a reset from the card
*/
timeout = 1000;
do {
- if (inb(host->card.io_intr) & 8)
+ if (readb(host->fast + INT_REG) & 8)
break;
udelay(1);
} while (--timeout);
@@ -353,19 +350,19 @@ void acornscsi_resetcard(AS_Host *host)
printk("scsi%d: timeout while resetting card\n",
host->host->host_no);
- sbic_arm_read(host->scsi.io_port, SBIC_ASR);
- sbic_arm_read(host->scsi.io_port, SBIC_SSR);
+ sbic_arm_read(host, SBIC_ASR);
+ sbic_arm_read(host, SBIC_SSR);
/* setup sbic - WD33C93A */
- sbic_arm_write(host->scsi.io_port, SBIC_OWNID, OWNID_EAF | host->host->this_id);
- sbic_arm_write(host->scsi.io_port, SBIC_CMND, CMND_RESET);
+ sbic_arm_write(host, SBIC_OWNID, OWNID_EAF | host->host->this_id);
+ sbic_arm_write(host, SBIC_CMND, CMND_RESET);
/*
* Command should cause a reset interrupt
*/
timeout = 1000;
do {
- if (inb(host->card.io_intr) & 8)
+ if (readb(host->fast + INT_REG) & 8)
break;
udelay(1);
} while (--timeout);
@@ -374,26 +371,26 @@ void acornscsi_resetcard(AS_Host *host)
printk("scsi%d: timeout while resetting card\n",
host->host->host_no);
- sbic_arm_read(host->scsi.io_port, SBIC_ASR);
- if (sbic_arm_read(host->scsi.io_port, SBIC_SSR) != 0x01)
+ sbic_arm_read(host, SBIC_ASR);
+ if (sbic_arm_read(host, SBIC_SSR) != 0x01)
printk(KERN_CRIT "scsi%d: WD33C93A didn't give enhanced reset interrupt\n",
host->host->host_no);
- sbic_arm_write(host->scsi.io_port, SBIC_CTRL, INIT_SBICDMA | CTRL_IDI);
- sbic_arm_write(host->scsi.io_port, SBIC_TIMEOUT, TIMEOUT_TIME);
- sbic_arm_write(host->scsi.io_port, SBIC_SYNCHTRANSFER, SYNCHTRANSFER_2DBA);
- sbic_arm_write(host->scsi.io_port, SBIC_SOURCEID, SOURCEID_ER | SOURCEID_DSP);
+ sbic_arm_write(host, SBIC_CTRL, INIT_SBICDMA | CTRL_IDI);
+ sbic_arm_write(host, SBIC_TIMEOUT, TIMEOUT_TIME);
+ sbic_arm_write(host, SBIC_SYNCHTRANSFER, SYNCHTRANSFER_2DBA);
+ sbic_arm_write(host, SBIC_SOURCEID, SOURCEID_ER | SOURCEID_DSP);
host->card.page_reg = 0x40;
- outb(host->card.page_reg, host->card.io_page);
+ writeb(host->card.page_reg, host->fast + PAGE_REG);
/* setup dmac - uPC71071 */
- dmac_write(host->dma.io_port, DMAC_INIT, 0);
+ dmac_write(host, DMAC_INIT, 0);
#ifdef USE_DMAC
- dmac_write(host->dma.io_port, DMAC_INIT, INIT_8BIT);
- dmac_write(host->dma.io_port, DMAC_CHANNEL, CHANNEL_0);
- dmac_write(host->dma.io_port, DMAC_DEVCON0, INIT_DEVCON0);
- dmac_write(host->dma.io_port, DMAC_DEVCON1, INIT_DEVCON1);
+ dmac_write(host, DMAC_INIT, INIT_8BIT);
+ dmac_write(host, DMAC_CHANNEL, CHANNEL_0);
+ dmac_write(host, DMAC_DEVCON0, INIT_DEVCON0);
+ dmac_write(host, DMAC_DEVCON1, INIT_DEVCON1);
#endif
host->SCpnt = NULL;
@@ -741,9 +738,9 @@ intr_ret_t acornscsi_kick(AS_Host *host)
* If we have an interrupt pending, then we may have been reselected.
* In this case, we don't want to write to the registers
*/
- if (!(sbic_arm_read(host->scsi.io_port, SBIC_ASR) & (ASR_INT|ASR_BSY|ASR_CIP))) {
- sbic_arm_write(host->scsi.io_port, SBIC_DESTID, SCpnt->device->id);
- sbic_arm_write(host->scsi.io_port, SBIC_CMND, CMND_SELWITHATN);
+ if (!(sbic_arm_read(host, SBIC_ASR) & (ASR_INT|ASR_BSY|ASR_CIP))) {
+ sbic_arm_write(host, SBIC_DESTID, SCpnt->device->id);
+ sbic_arm_write(host, SBIC_CMND, CMND_SELWITHATN);
}
/*
@@ -807,7 +804,7 @@ static void acornscsi_done(AS_Host *host, struct scsi_cmnd **SCpntp,
struct scsi_cmnd *SCpnt = *SCpntp;
/* clean up */
- sbic_arm_write(host->scsi.io_port, SBIC_SOURCEID, SOURCEID_ER | SOURCEID_DSP);
+ sbic_arm_write(host, SBIC_SOURCEID, SOURCEID_ER | SOURCEID_DSP);
host->stats.fins += 1;
@@ -918,13 +915,13 @@ static
void acornscsi_data_read(AS_Host *host, char *ptr,
unsigned int start_addr, unsigned int length)
{
- extern void __acornscsi_in(int port, char *buf, int len);
+ extern void __acornscsi_in(void __iomem *, char *buf, int len);
unsigned int page, offset, len = length;
page = (start_addr >> 12);
offset = start_addr & ((1 << 12) - 1);
- outb((page & 0x3f) | host->card.page_reg, host->card.io_page);
+ writeb((page & 0x3f) | host->card.page_reg, host->fast + PAGE_REG);
while (len > 0) {
unsigned int this_len;
@@ -934,7 +931,7 @@ void acornscsi_data_read(AS_Host *host, char *ptr,
else
this_len = len;
- __acornscsi_in(host->card.io_ram + (offset << 1), ptr, this_len);
+ __acornscsi_in(host->base + (offset << 1), ptr, this_len);
offset += this_len;
ptr += this_len;
@@ -943,10 +940,10 @@ void acornscsi_data_read(AS_Host *host, char *ptr,
if (offset == (1 << 12)) {
offset = 0;
page ++;
- outb((page & 0x3f) | host->card.page_reg, host->card.io_page);
+ writeb((page & 0x3f) | host->card.page_reg, host->fast + PAGE_REG);
}
}
- outb(host->card.page_reg, host->card.io_page);
+ writeb(host->card.page_reg, host->fast + PAGE_REG);
}
/*
@@ -963,13 +960,13 @@ static
void acornscsi_data_write(AS_Host *host, char *ptr,
unsigned int start_addr, unsigned int length)
{
- extern void __acornscsi_out(int port, char *buf, int len);
+ extern void __acornscsi_out(void __iomem *, char *buf, int len);
unsigned int page, offset, len = length;
page = (start_addr >> 12);
offset = start_addr & ((1 << 12) - 1);
- outb((page & 0x3f) | host->card.page_reg, host->card.io_page);
+ writeb((page & 0x3f) | host->card.page_reg, host->fast + PAGE_REG);
while (len > 0) {
unsigned int this_len;
@@ -979,7 +976,7 @@ void acornscsi_data_write(AS_Host *host, char *ptr,
else
this_len = len;
- __acornscsi_out(host->card.io_ram + (offset << 1), ptr, this_len);
+ __acornscsi_out(host->base + (offset << 1), ptr, this_len);
offset += this_len;
ptr += this_len;
@@ -988,10 +985,10 @@ void acornscsi_data_write(AS_Host *host, char *ptr,
if (offset == (1 << 12)) {
offset = 0;
page ++;
- outb((page & 0x3f) | host->card.page_reg, host->card.io_page);
+ writeb((page & 0x3f) | host->card.page_reg, host->fast + PAGE_REG);
}
}
- outb(host->card.page_reg, host->card.io_page);
+ writeb(host->card.page_reg, host->fast + PAGE_REG);
}
/* =========================================================================================
@@ -1008,8 +1005,8 @@ void acornscsi_data_write(AS_Host *host, char *ptr,
static inline
void acornscsi_dma_stop(AS_Host *host)
{
- dmac_write(host->dma.io_port, DMAC_MASKREG, MASK_ON);
- dmac_clearintr(host->dma.io_intr_clear);
+ dmac_write(host, DMAC_MASKREG, MASK_ON);
+ dmac_clearintr(host);
#if (DEBUG & DEBUG_DMA)
DBG(host->SCpnt, acornscsi_dumpdma(host, "stop"));
@@ -1031,7 +1028,7 @@ void acornscsi_dma_setup(AS_Host *host, dmadir_t direction)
host->dma.direction = direction;
- dmac_write(host->dma.io_port, DMAC_MASKREG, MASK_ON);
+ dmac_write(host, DMAC_MASKREG, MASK_ON);
if (direction == DMA_OUT) {
#if (DEBUG & DEBUG_NO_WRITE)
@@ -1062,13 +1059,13 @@ void acornscsi_dma_setup(AS_Host *host, dmadir_t direction)
length);
length -= 1;
- dmac_write(host->dma.io_port, DMAC_TXCNTLO, length);
- dmac_write(host->dma.io_port, DMAC_TXCNTHI, length >> 8);
- dmac_write(host->dma.io_port, DMAC_TXADRLO, address);
- dmac_write(host->dma.io_port, DMAC_TXADRMD, address >> 8);
- dmac_write(host->dma.io_port, DMAC_TXADRHI, 0);
- dmac_write(host->dma.io_port, DMAC_MODECON, mode);
- dmac_write(host->dma.io_port, DMAC_MASKREG, MASK_OFF);
+ dmac_write(host, DMAC_TXCNTLO, length);
+ dmac_write(host, DMAC_TXCNTHI, length >> 8);
+ dmac_write(host, DMAC_TXADRLO, address);
+ dmac_write(host, DMAC_TXADRMD, address >> 8);
+ dmac_write(host, DMAC_TXADRHI, 0);
+ dmac_write(host, DMAC_MODECON, mode);
+ dmac_write(host, DMAC_MASKREG, MASK_OFF);
#if (DEBUG & DEBUG_DMA)
DBG(host->SCpnt, acornscsi_dumpdma(host, "strt"));
@@ -1088,8 +1085,8 @@ void acornscsi_dma_setup(AS_Host *host, dmadir_t direction)
static
void acornscsi_dma_cleanup(AS_Host *host)
{
- dmac_write(host->dma.io_port, DMAC_MASKREG, MASK_ON);
- dmac_clearintr(host->dma.io_intr_clear);
+ dmac_write(host, DMAC_MASKREG, MASK_ON);
+ dmac_clearintr(host);
/*
* Check for a pending transfer
@@ -1116,7 +1113,7 @@ void acornscsi_dma_cleanup(AS_Host *host)
/*
* Calculate number of bytes transferred from DMA.
*/
- transferred = dmac_address(host->dma.io_port) - host->dma.start_addr;
+ transferred = dmac_address(host) - host->dma.start_addr;
host->dma.transferred += transferred;
if (host->dma.direction == DMA_IN)
@@ -1152,13 +1149,13 @@ void acornscsi_dma_intr(AS_Host *host)
DBG(host->SCpnt, acornscsi_dumpdma(host, "inti"));
#endif
- dmac_write(host->dma.io_port, DMAC_MASKREG, MASK_ON);
- dmac_clearintr(host->dma.io_intr_clear);
+ dmac_write(host, DMAC_MASKREG, MASK_ON);
+ dmac_clearintr(host);
/*
* Calculate amount transferred via DMA
*/
- transferred = dmac_address(host->dma.io_port) - host->dma.start_addr;
+ transferred = dmac_address(host) - host->dma.start_addr;
host->dma.transferred += transferred;
/*
@@ -1190,12 +1187,12 @@ void acornscsi_dma_intr(AS_Host *host)
length);
length -= 1;
- dmac_write(host->dma.io_port, DMAC_TXCNTLO, length);
- dmac_write(host->dma.io_port, DMAC_TXCNTHI, length >> 8);
- dmac_write(host->dma.io_port, DMAC_TXADRLO, address);
- dmac_write(host->dma.io_port, DMAC_TXADRMD, address >> 8);
- dmac_write(host->dma.io_port, DMAC_TXADRHI, 0);
- dmac_write(host->dma.io_port, DMAC_MASKREG, MASK_OFF);
+ dmac_write(host, DMAC_TXCNTLO, length);
+ dmac_write(host, DMAC_TXCNTHI, length >> 8);
+ dmac_write(host, DMAC_TXADRLO, address);
+ dmac_write(host, DMAC_TXADRMD, address >> 8);
+ dmac_write(host, DMAC_TXADRHI, 0);
+ dmac_write(host, DMAC_MASKREG, MASK_OFF);
#if (DEBUG & DEBUG_DMA)
DBG(host->SCpnt, acornscsi_dumpdma(host, "into"));
@@ -1209,15 +1206,15 @@ void acornscsi_dma_intr(AS_Host *host)
* attention condition. We continue giving one byte until
* the device recognises the attention.
*/
- if (dmac_read(host->dma.io_port, DMAC_STATUS) & STATUS_RQ0) {
+ if (dmac_read(host, DMAC_STATUS) & STATUS_RQ0) {
acornscsi_abortcmd(host, host->SCpnt->tag);
- dmac_write(host->dma.io_port, DMAC_TXCNTLO, 0);
- dmac_write(host->dma.io_port, DMAC_TXCNTHI, 0);
- dmac_write(host->dma.io_port, DMAC_TXADRLO, 0);
- dmac_write(host->dma.io_port, DMAC_TXADRMD, 0);
- dmac_write(host->dma.io_port, DMAC_TXADRHI, 0);
- dmac_write(host->dma.io_port, DMAC_MASKREG, MASK_OFF);
+ dmac_write(host, DMAC_TXCNTLO, 0);
+ dmac_write(host, DMAC_TXCNTHI, 0);
+ dmac_write(host, DMAC_TXADRLO, 0);
+ dmac_write(host, DMAC_TXADRMD, 0);
+ dmac_write(host, DMAC_TXADRHI, 0);
+ dmac_write(host, DMAC_MASKREG, MASK_OFF);
}
#endif
}
@@ -1271,9 +1268,9 @@ void acornscsi_dma_adjust(AS_Host *host)
host->dma.xfer_setup = 0;
else {
transferred += host->dma.start_addr;
- dmac_write(host->dma.io_port, DMAC_TXADRLO, transferred);
- dmac_write(host->dma.io_port, DMAC_TXADRMD, transferred >> 8);
- dmac_write(host->dma.io_port, DMAC_TXADRHI, transferred >> 16);
+ dmac_write(host, DMAC_TXADRLO, transferred);
+ dmac_write(host, DMAC_TXADRMD, transferred >> 8);
+ dmac_write(host, DMAC_TXADRHI, transferred >> 16);
#if (DEBUG & (DEBUG_DMA|DEBUG_WRITE))
DBG(host->SCpnt, acornscsi_dumpdma(host, "adjo"));
#endif
@@ -1292,12 +1289,12 @@ acornscsi_write_pio(AS_Host *host, char *bytes, int *ptr, int len, unsigned int
int my_ptr = *ptr;
while (my_ptr < len) {
- asr = sbic_arm_read(host->scsi.io_port, SBIC_ASR);
+ asr = sbic_arm_read(host, SBIC_ASR);
if (asr & ASR_DBR) {
timeout = max_timeout;
- sbic_arm_write(host->scsi.io_port, SBIC_DATA, bytes[my_ptr++]);
+ sbic_arm_write(host, SBIC_DATA, bytes[my_ptr++]);
} else if (asr & ASR_INT)
break;
else if (--timeout == 0)
@@ -1320,9 +1317,9 @@ acornscsi_sendcommand(AS_Host *host)
{
struct scsi_cmnd *SCpnt = host->SCpnt;
- sbic_arm_write(host->scsi.io_port, SBIC_TRANSCNTH, 0);
- sbic_arm_writenext(host->scsi.io_port, 0);
- sbic_arm_writenext(host->scsi.io_port, SCpnt->cmd_len - host->scsi.SCp.sent_command);
+ sbic_arm_write(host, SBIC_TRANSCNTH, 0);
+ sbic_arm_writenext(host, 0);
+ sbic_arm_writenext(host, SCpnt->cmd_len - host->scsi.SCp.sent_command);
acornscsi_sbic_issuecmd(host, CMND_XFERINFO);
@@ -1351,7 +1348,7 @@ void acornscsi_sendmessage(AS_Host *host)
acornscsi_sbic_wait(host, ASR_DBR, ASR_DBR, 1000, "sending message 1");
- sbic_arm_write(host->scsi.io_port, SBIC_DATA, NOP);
+ sbic_arm_write(host, SBIC_DATA, NOP);
host->scsi.last_message = NOP;
#if (DEBUG & DEBUG_MESSAGES)
@@ -1365,7 +1362,7 @@ void acornscsi_sendmessage(AS_Host *host)
acornscsi_sbic_wait(host, ASR_DBR, ASR_DBR, 1000, "sending message 2");
- sbic_arm_write(host->scsi.io_port, SBIC_DATA, msg->msg[0]);
+ sbic_arm_write(host, SBIC_DATA, msg->msg[0]);
host->scsi.last_message = msg->msg[0];
#if (DEBUG & DEBUG_MESSAGES)
@@ -1382,9 +1379,9 @@ void acornscsi_sendmessage(AS_Host *host)
* initiator. This provides an interlock so that the
* initiator can determine which message byte is rejected.
*/
- sbic_arm_write(host->scsi.io_port, SBIC_TRANSCNTH, 0);
- sbic_arm_writenext(host->scsi.io_port, 0);
- sbic_arm_writenext(host->scsi.io_port, message_length);
+ sbic_arm_write(host, SBIC_TRANSCNTH, 0);
+ sbic_arm_writenext(host, 0);
+ sbic_arm_writenext(host, message_length);
acornscsi_sbic_issuecmd(host, CMND_XFERINFO);
msgnr = 0;
@@ -1421,7 +1418,7 @@ void acornscsi_readstatusbyte(AS_Host *host)
{
acornscsi_sbic_issuecmd(host, CMND_XFERINFO|CMND_SBT);
acornscsi_sbic_wait(host, ASR_DBR, ASR_DBR, 1000, "reading status byte");
- host->scsi.SCp.Status = sbic_arm_read(host->scsi.io_port, SBIC_DATA);
+ host->scsi.SCp.Status = sbic_arm_read(host, SBIC_DATA);
}
/*
@@ -1438,12 +1435,12 @@ unsigned char acornscsi_readmessagebyte(AS_Host *host)
acornscsi_sbic_wait(host, ASR_DBR, ASR_DBR, 1000, "for message byte");
- message = sbic_arm_read(host->scsi.io_port, SBIC_DATA);
+ message = sbic_arm_read(host, SBIC_DATA);
/* wait for MSGIN-XFER-PAUSED */
acornscsi_sbic_wait(host, ASR_INT, ASR_INT, 1000, "for interrupt after message byte");
- sbic_arm_read(host->scsi.io_port, SBIC_SSR);
+ sbic_arm_read(host, SBIC_SSR);
return message;
}
@@ -1480,7 +1477,7 @@ void acornscsi_message(AS_Host *host)
/* wait for next msg-in */
acornscsi_sbic_wait(host, ASR_INT, ASR_INT, 1000, "for interrupt after negate ack");
- sbic_arm_read(host->scsi.io_port, SBIC_SSR);
+ sbic_arm_read(host, SBIC_SSR);
}
} while (msgidx < msglen);
@@ -1602,7 +1599,7 @@ void acornscsi_message(AS_Host *host)
host->host->host_no, acornscsi_target(host));
host->device[host->SCpnt->device->id].sync_xfer = SYNCHTRANSFER_2DBA;
host->device[host->SCpnt->device->id].sync_state = SYNC_ASYNCHRONOUS;
- sbic_arm_write(host->scsi.io_port, SBIC_SYNCHTRANSFER, host->device[host->SCpnt->device->id].sync_xfer);
+ sbic_arm_write(host, SBIC_SYNCHTRANSFER, host->device[host->SCpnt->device->id].sync_xfer);
break;
default:
@@ -1652,7 +1649,7 @@ void acornscsi_message(AS_Host *host)
host->device[host->SCpnt->device->id].sync_xfer =
calc_sync_xfer(period * 4, length);
}
- sbic_arm_write(host->scsi.io_port, SBIC_SYNCHTRANSFER, host->device[host->SCpnt->device->id].sync_xfer);
+ sbic_arm_write(host, SBIC_SYNCHTRANSFER, host->device[host->SCpnt->device->id].sync_xfer);
break;
#else
/* We do not accept synchronous transfers. Respond with a
@@ -1792,10 +1789,10 @@ int acornscsi_starttransfer(AS_Host *host)
residual = scsi_bufflen(host->SCpnt) - host->scsi.SCp.scsi_xferred;
- sbic_arm_write(host->scsi.io_port, SBIC_SYNCHTRANSFER, host->device[host->SCpnt->device->id].sync_xfer);
- sbic_arm_writenext(host->scsi.io_port, residual >> 16);
- sbic_arm_writenext(host->scsi.io_port, residual >> 8);
- sbic_arm_writenext(host->scsi.io_port, residual);
+ sbic_arm_write(host, SBIC_SYNCHTRANSFER, host->device[host->SCpnt->device->id].sync_xfer);
+ sbic_arm_writenext(host, residual >> 16);
+ sbic_arm_writenext(host, residual >> 8);
+ sbic_arm_writenext(host, residual);
acornscsi_sbic_issuecmd(host, CMND_XFERINFO);
return 1;
}
@@ -1816,7 +1813,7 @@ int acornscsi_reconnect(AS_Host *host)
{
unsigned int target, lun, ok = 0;
- target = sbic_arm_read(host->scsi.io_port, SBIC_SOURCEID);
+ target = sbic_arm_read(host, SBIC_SOURCEID);
if (!(target & 8))
printk(KERN_ERR "scsi%d: invalid source id after reselection "
@@ -1832,7 +1829,7 @@ int acornscsi_reconnect(AS_Host *host)
host->SCpnt = NULL;
}
- lun = sbic_arm_read(host->scsi.io_port, SBIC_DATA) & 7;
+ lun = sbic_arm_read(host, SBIC_DATA) & 7;
host->scsi.reconnected.target = target;
host->scsi.reconnected.lun = lun;
@@ -1952,7 +1949,7 @@ static
void acornscsi_abortcmd(AS_Host *host, unsigned char tag)
{
host->scsi.phase = PHASE_ABORTED;
- sbic_arm_write(host->scsi.io_port, SBIC_CMND, CMND_ASSERTATN);
+ sbic_arm_write(host, SBIC_CMND, CMND_ASSERTATN);
msgqueue_flush(&host->scsi.msgs);
#ifdef CONFIG_SCSI_ACORNSCSI_TAGGED_QUEUE
@@ -1979,11 +1976,11 @@ intr_ret_t acornscsi_sbicintr(AS_Host *host, int in_irq)
{
unsigned int asr, ssr;
- asr = sbic_arm_read(host->scsi.io_port, SBIC_ASR);
+ asr = sbic_arm_read(host, SBIC_ASR);
if (!(asr & ASR_INT))
return INTR_IDLE;
- ssr = sbic_arm_read(host->scsi.io_port, SBIC_SSR);
+ ssr = sbic_arm_read(host, SBIC_SSR);
#if (DEBUG & DEBUG_PHASES)
print_sbic_status(asr, ssr, host->scsi.phase);
@@ -1999,15 +1996,15 @@ intr_ret_t acornscsi_sbicintr(AS_Host *host, int in_irq)
printk(KERN_ERR "scsi%d: reset in standard mode but wanted advanced mode.\n",
host->host->host_no);
/* setup sbic - WD33C93A */
- sbic_arm_write(host->scsi.io_port, SBIC_OWNID, OWNID_EAF | host->host->this_id);
- sbic_arm_write(host->scsi.io_port, SBIC_CMND, CMND_RESET);
+ sbic_arm_write(host, SBIC_OWNID, OWNID_EAF | host->host->this_id);
+ sbic_arm_write(host, SBIC_CMND, CMND_RESET);
return INTR_IDLE;
case 0x01: /* reset state - advanced */
- sbic_arm_write(host->scsi.io_port, SBIC_CTRL, INIT_SBICDMA | CTRL_IDI);
- sbic_arm_write(host->scsi.io_port, SBIC_TIMEOUT, TIMEOUT_TIME);
- sbic_arm_write(host->scsi.io_port, SBIC_SYNCHTRANSFER, SYNCHTRANSFER_2DBA);
- sbic_arm_write(host->scsi.io_port, SBIC_SOURCEID, SOURCEID_ER | SOURCEID_DSP);
+ sbic_arm_write(host, SBIC_CTRL, INIT_SBICDMA | CTRL_IDI);
+ sbic_arm_write(host, SBIC_TIMEOUT, TIMEOUT_TIME);
+ sbic_arm_write(host, SBIC_SYNCHTRANSFER, SYNCHTRANSFER_2DBA);
+ sbic_arm_write(host, SBIC_SOURCEID, SOURCEID_ER | SOURCEID_DSP);
msgqueue_flush(&host->scsi.msgs);
return INTR_IDLE;
@@ -2025,10 +2022,10 @@ intr_ret_t acornscsi_sbicintr(AS_Host *host, int in_irq)
msgqueue_flush(&host->scsi.msgs);
host->dma.transferred = host->scsi.SCp.scsi_xferred;
/* 33C93 gives next interrupt indicating bus phase */
- asr = sbic_arm_read(host->scsi.io_port, SBIC_ASR);
+ asr = sbic_arm_read(host, SBIC_ASR);
if (!(asr & ASR_INT))
break;
- ssr = sbic_arm_read(host->scsi.io_port, SBIC_SSR);
+ ssr = sbic_arm_read(host, SBIC_SSR);
ADD_STATUS(8, ssr, host->scsi.phase, 1);
ADD_STATUS(host->SCpnt->device->id, ssr, host->scsi.phase, 1);
goto connected;
@@ -2476,11 +2473,11 @@ acornscsi_intr(int irq, void *dev_id)
do {
ret = INTR_IDLE;
- iostatus = inb(host->card.io_intr);
+ iostatus = readb(host->fast + INT_REG);
if (iostatus & 2) {
acornscsi_dma_intr(host);
- iostatus = inb(host->card.io_intr);
+ iostatus = readb(host->fast + INT_REG);
}
if (iostatus & 8)
@@ -2655,7 +2652,7 @@ static enum res_abort acornscsi_do_abort(AS_Host *host, struct scsi_cmnd *SCpnt)
* busylun bit.
*/
case PHASE_CONNECTED:
- sbic_arm_write(host->scsi.io_port, SBIC_CMND, CMND_DISCONNECT);
+ sbic_arm_write(host, SBIC_CMND, CMND_DISCONNECT);
host->SCpnt = NULL;
res = res_success_clear;
break;
@@ -2699,8 +2696,8 @@ int acornscsi_abort(struct scsi_cmnd *SCpnt)
#if (DEBUG & DEBUG_ABORT)
{
int asr, ssr;
- asr = sbic_arm_read(host->scsi.io_port, SBIC_ASR);
- ssr = sbic_arm_read(host->scsi.io_port, SBIC_SSR);
+ asr = sbic_arm_read(host, SBIC_ASR);
+ ssr = sbic_arm_read(host, SBIC_SSR);
printk(KERN_WARNING "acornscsi_abort: ");
print_sbic_status(asr, ssr, host->scsi.phase);
@@ -2731,9 +2728,7 @@ int acornscsi_abort(struct scsi_cmnd *SCpnt)
//#if (DEBUG & DEBUG_ABORT)
printk("success\n");
//#endif
- SCpnt->result = DID_ABORT << 16;
- SCpnt->scsi_done(SCpnt);
- result = SCSI_ABORT_SUCCESS;
+ result = SUCCESS;
break;
/*
@@ -2745,7 +2740,7 @@ int acornscsi_abort(struct scsi_cmnd *SCpnt)
//#if (DEBUG & DEBUG_ABORT)
printk("snooze\n");
//#endif
- result = SCSI_ABORT_SNOOZE;
+ result = FAILED;
break;
/*
@@ -2755,11 +2750,7 @@ int acornscsi_abort(struct scsi_cmnd *SCpnt)
default:
case res_not_running:
acornscsi_dumplog(host, SCpnt->device->id);
-#if (DEBUG & DEBUG_ABORT)
- result = SCSI_ABORT_SNOOZE;
-#else
- result = SCSI_ABORT_NOT_RUNNING;
-#endif
+ result = FAILED;
//#if (DEBUG & DEBUG_ABORT)
printk("not running\n");
//#endif
@@ -2770,13 +2761,12 @@ int acornscsi_abort(struct scsi_cmnd *SCpnt)
}
/*
- * Prototype: int acornscsi_reset(struct scsi_cmnd *SCpnt, unsigned int reset_flags)
+ * Prototype: int acornscsi_reset(struct scsi_cmnd *SCpnt)
* Purpose : reset a command on this host/reset this host
* Params : SCpnt - command causing reset
- * result - what type of reset to perform
* Returns : one of SCSI_RESET_ macros
*/
-int acornscsi_reset(struct scsi_cmnd *SCpnt, unsigned int reset_flags)
+int acornscsi_bus_reset(struct scsi_cmnd *SCpnt)
{
AS_Host *host = (AS_Host *)SCpnt->device->host->hostdata;
struct scsi_cmnd *SCptr;
@@ -2787,8 +2777,8 @@ int acornscsi_reset(struct scsi_cmnd *SCpnt, unsigned int reset_flags)
{
int asr, ssr;
- asr = sbic_arm_read(host->scsi.io_port, SBIC_ASR);
- ssr = sbic_arm_read(host->scsi.io_port, SBIC_SSR);
+ asr = sbic_arm_read(host, SBIC_ASR);
+ ssr = sbic_arm_read(host, SBIC_SSR);
printk(KERN_WARNING "acornscsi_reset: ");
print_sbic_status(asr, ssr, host->scsi.phase);
@@ -2798,28 +2788,16 @@ int acornscsi_reset(struct scsi_cmnd *SCpnt, unsigned int reset_flags)
acornscsi_dma_stop(host);
- SCptr = host->SCpnt;
-
/*
* do hard reset. This resets all devices on this host, and so we
* must set the reset status on all commands.
*/
acornscsi_resetcard(host);
- /*
- * report reset on commands current connected/disconnected
- */
- acornscsi_reportstatus(&host->SCpnt, &SCptr, DID_RESET);
-
while ((SCptr = queue_remove(&host->queues.disconnected)) != NULL)
- acornscsi_reportstatus(&SCptr, &SCpnt, DID_RESET);
-
- if (SCpnt) {
- SCpnt->result = DID_RESET << 16;
- SCpnt->scsi_done(SCpnt);
- }
+ ;
- return SCSI_RESET_BUS_RESET | SCSI_RESET_HOST_RESET | SCSI_RESET_SUCCESS;
+ return SUCCESS;
}
/*==============================================================================================
@@ -2850,7 +2828,7 @@ char *acornscsi_info(struct Scsi_Host *host)
" LINK"
#endif
#if (DEBUG & DEBUG_NO_WRITE)
- " NOWRITE ("NO_WRITE_STR")"
+ " NOWRITE (" __stringify(NO_WRITE) ")"
#endif
, host->hostt->name, host->io_port, host->irq,
VER_MAJOR, VER_MINOR, VER_PATCH);
@@ -2881,15 +2859,15 @@ int acornscsi_proc_info(struct Scsi_Host *instance, char *buffer, char **start,
" LINK"
#endif
#if (DEBUG & DEBUG_NO_WRITE)
- " NOWRITE ("NO_WRITE_STR")"
+ " NOWRITE (" __stringify(NO_WRITE) ")"
#endif
"\n\n", VER_MAJOR, VER_MINOR, VER_PATCH);
- p += sprintf(p, "SBIC: WD33C93A Address: %08X IRQ : %d\n",
- host->scsi.io_port, host->scsi.irq);
+ p += sprintf(p, "SBIC: WD33C93A Address: %p IRQ : %d\n",
+ host->base + SBIC_REGIDX, host->scsi.irq);
#ifdef USE_DMAC
- p += sprintf(p, "DMAC: uPC71071 Address: %08X IRQ : %d\n\n",
- host->dma.io_port, host->scsi.irq);
+ p += sprintf(p, "DMAC: uPC71071 Address: %p IRQ : %d\n\n",
+ host->base + DMAC_OFFSET, host->scsi.irq);
#endif
p += sprintf(p, "Statistics:\n"
@@ -2976,9 +2954,8 @@ static struct scsi_host_template acornscsi_template = {
.name = "AcornSCSI",
.info = acornscsi_info,
.queuecommand = acornscsi_queuecmd,
-#warning fixme
- .abort = acornscsi_abort,
- .reset = acornscsi_reset,
+ .eh_abort_handler = acornscsi_abort,
+ .eh_bus_reset_handler = acornscsi_bus_reset,
.can_queue = 16,
.this_id = 7,
.sg_tablesize = SG_ALL,
@@ -2992,48 +2969,37 @@ acornscsi_probe(struct expansion_card *ec, const struct ecard_id *id)
{
struct Scsi_Host *host;
AS_Host *ashost;
- int ret = -ENOMEM;
+ int ret;
- host = scsi_host_alloc(&acornscsi_template, sizeof(AS_Host));
- if (!host)
+ ret = ecard_request_resources(ec);
+ if (ret)
goto out;
+ host = scsi_host_alloc(&acornscsi_template, sizeof(AS_Host));
+ if (!host) {
+ ret = -ENOMEM;
+ goto out_release;
+ }
+
ashost = (AS_Host *)host->hostdata;
- host->io_port = ecard_address(ec, ECARD_MEMC, 0);
- host->irq = ec->irq;
+ ashost->base = ecardm_iomap(ec, ECARD_RES_MEMC, 0, 0);
+ ashost->fast = ecardm_iomap(ec, ECARD_RES_IOCFAST, 0, 0);
+ if (!ashost->base || !ashost->fast)
+ goto out_put;
- ashost->host = host;
- ashost->scsi.io_port = ioaddr(host->io_port + 0x800);
- ashost->scsi.irq = host->irq;
- ashost->card.io_intr = POD_SPACE(host->io_port) + 0x800;
- ashost->card.io_page = POD_SPACE(host->io_port) + 0xc00;
- ashost->card.io_ram = ioaddr(host->io_port);
- ashost->dma.io_port = host->io_port + 0xc00;
- ashost->dma.io_intr_clear = POD_SPACE(host->io_port) + 0x800;
+ host->irq = ec->irq;
+ ashost->host = host;
+ ashost->scsi.irq = host->irq;
- ec->irqaddr = (char *)ioaddr(ashost->card.io_intr);
+ ec->irqaddr = ashost->fast + INT_REG;
ec->irqmask = 0x0a;
- ret = -EBUSY;
- if (!request_region(host->io_port + 0x800, 2, "acornscsi(sbic)"))
- goto err_1;
- if (!request_region(ashost->card.io_intr, 1, "acornscsi(intr)"))
- goto err_2;
- if (!request_region(ashost->card.io_page, 1, "acornscsi(page)"))
- goto err_3;
-#ifdef USE_DMAC
- if (!request_region(ashost->dma.io_port, 256, "acornscsi(dmac)"))
- goto err_4;
-#endif
- if (!request_region(host->io_port, 2048, "acornscsi(ram)"))
- goto err_5;
-
ret = request_irq(host->irq, acornscsi_intr, IRQF_DISABLED, "acornscsi", ashost);
if (ret) {
printk(KERN_CRIT "scsi%d: IRQ%d not free: %d\n",
host->host_no, ashost->scsi.irq, ret);
- goto err_6;
+ goto out_put;
}
memset(&ashost->stats, 0, sizeof (ashost->stats));
@@ -3045,27 +3011,22 @@ acornscsi_probe(struct expansion_card *ec, const struct ecard_id *id)
ret = scsi_add_host(host, &ec->dev);
if (ret)
- goto err_7;
+ goto out_irq;
scsi_scan_host(host);
goto out;
- err_7:
+ out_irq:
free_irq(host->irq, ashost);
- err_6:
- release_region(host->io_port, 2048);
- err_5:
-#ifdef USE_DMAC
- release_region(ashost->dma.io_port, 256);
-#endif
- err_4:
- release_region(ashost->card.io_page, 1);
- err_3:
- release_region(ashost->card.io_intr, 1);
- err_2:
- release_region(host->io_port + 0x800, 2);
- err_1:
+ msgqueue_free(&ashost->scsi.msgs);
+ queue_free(&ashost->queues.disconnected);
+ queue_free(&ashost->queues.issue);
+ out_put:
+ ecardm_iounmap(ec, ashost->fast);
+ ecardm_iounmap(ec, ashost->base);
scsi_host_put(host);
+ out_release:
+ ecard_release_resources(ec);
out:
return ret;
}
@@ -3081,20 +3042,17 @@ static void __devexit acornscsi_remove(struct expansion_card *ec)
/*
* Put card into RESET state
*/
- outb(0x80, ashost->card.io_page);
+ writeb(0x80, ashost->fast + PAGE_REG);
free_irq(host->irq, ashost);
- release_region(host->io_port + 0x800, 2);
- release_region(ashost->card.io_intr, 1);
- release_region(ashost->card.io_page, 1);
- release_region(ashost->dma.io_port, 256);
- release_region(host->io_port, 2048);
-
msgqueue_free(&ashost->scsi.msgs);
queue_free(&ashost->queues.disconnected);
queue_free(&ashost->queues.issue);
+ ecardm_iounmap(ec, ashost->fast);
+ ecardm_iounmap(ec, ashost->base);
scsi_host_put(host);
+ ecard_release_resources(ec);
}
static const struct ecard_id acornscsi_cids[] = {
diff --git a/drivers/scsi/arm/acornscsi.h b/drivers/scsi/arm/acornscsi.h
index d11424b89f4..8d2172a0b35 100644
--- a/drivers/scsi/arm/acornscsi.h
+++ b/drivers/scsi/arm/acornscsi.h
@@ -179,7 +179,6 @@
/* miscellaneous internal variables */
-#define POD_SPACE(x) ((x) + 0xd0000)
#define MASK_ON (MASKREG_M3|MASKREG_M2|MASKREG_M1|MASKREG_M0)
#define MASK_OFF (MASKREG_M3|MASKREG_M2|MASKREG_M1)
@@ -279,10 +278,11 @@ typedef struct acornscsi_hostdata {
struct Scsi_Host *host; /* host */
struct scsi_cmnd *SCpnt; /* currently processing command */
struct scsi_cmnd *origSCpnt; /* original connecting command */
+ void __iomem *base; /* memc base address */
+ void __iomem *fast; /* fast ioc base address */
/* driver information */
struct {
- unsigned int io_port; /* base address of WD33C93 */
unsigned int irq; /* interrupt */
phase_t phase; /* current phase */
@@ -329,8 +329,6 @@ typedef struct acornscsi_hostdata {
/* DMA info */
struct {
- unsigned int io_port; /* base address of DMA controller */
- unsigned int io_intr_clear; /* address of DMA interrupt clear */
unsigned int free_addr; /* next free address */
unsigned int start_addr; /* start address of current transfer */
dmadir_t direction; /* dma direction */
@@ -345,9 +343,6 @@ typedef struct acornscsi_hostdata {
/* card info */
struct {
- unsigned int io_intr; /* base address of interrupt id reg */
- unsigned int io_page; /* base address of page reg */
- unsigned int io_ram; /* base address of RAM access */
unsigned char page_reg; /* current setting of page reg */
} card;
diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c
index db6de5e6afb..7d311541c76 100644
--- a/drivers/scsi/atp870u.c
+++ b/drivers/scsi/atp870u.c
@@ -747,7 +747,7 @@ static void send_s870(struct atp_unit *dev,unsigned char c)
dev->quhd[c] = 0;
}
workreq = dev->quereq[c][dev->quhd[c]];
- if (dev->id[c][scmd_id(workreq)].curr_req == 0) {
+ if (dev->id[c][scmd_id(workreq)].curr_req == NULL) {
dev->id[c][scmd_id(workreq)].curr_req = workreq;
dev->last_cmd[c] = scmd_id(workreq);
goto cmd_subp;
diff --git a/drivers/scsi/ch.c b/drivers/scsi/ch.c
index c4b938bc30d..aa2011b6468 100644
--- a/drivers/scsi/ch.c
+++ b/drivers/scsi/ch.c
@@ -22,6 +22,7 @@
#include <linux/chio.h> /* here are all the ioctls */
#include <linux/mutex.h>
#include <linux/idr.h>
+#include <linux/smp_lock.h>
#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
@@ -571,16 +572,19 @@ ch_open(struct inode *inode, struct file *file)
scsi_changer *ch;
int minor = iminor(inode);
+ lock_kernel();
spin_lock(&ch_index_lock);
ch = idr_find(&ch_index_idr, minor);
if (NULL == ch || scsi_device_get(ch->device)) {
spin_unlock(&ch_index_lock);
+ unlock_kernel();
return -ENXIO;
}
spin_unlock(&ch_index_lock);
file->private_data = ch;
+ unlock_kernel();
return 0;
}
diff --git a/drivers/scsi/dpt/dptsig.h b/drivers/scsi/dpt/dptsig.h
index 72c8992fdf2..a6644b332b5 100644
--- a/drivers/scsi/dpt/dptsig.h
+++ b/drivers/scsi/dpt/dptsig.h
@@ -85,7 +85,7 @@ typedef unsigned int sigINT;
/* ------------------------------------------------------------------ */
/* What type of processor the file is meant to run on. */
/* This will let us know whether to read sigWORDs as high/low or low/high. */
-#define PROC_INTEL 0x00 /* Intel 80x86 */
+#define PROC_INTEL 0x00 /* Intel 80x86/ia64 */
#define PROC_MOTOROLA 0x01 /* Motorola 68K */
#define PROC_MIPS4000 0x02 /* MIPS RISC 4000 */
#define PROC_ALPHA 0x03 /* DEC Alpha */
@@ -104,6 +104,7 @@ typedef unsigned int sigINT;
#define PROC_486 0x08 /* Intel 80486 */
#define PROC_PENTIUM 0x10 /* Intel 586 aka P5 aka Pentium */
#define PROC_SEXIUM 0x20 /* Intel 686 aka P6 aka Pentium Pro or MMX */
+#define PROC_IA64 0x40 /* Intel IA64 processor */
/* PROC_i960: */
#define PROC_960RX 0x01 /* Intel 80960RC/RD */
diff --git a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c
index 8508816f303..2bc30e32b67 100644
--- a/drivers/scsi/dpt_i2o.c
+++ b/drivers/scsi/dpt_i2o.c
@@ -49,6 +49,7 @@ MODULE_DESCRIPTION("Adaptec I2O RAID Driver");
#include <linux/kernel.h> /* for printk */
#include <linux/sched.h>
#include <linux/reboot.h>
+#include <linux/smp_lock.h>
#include <linux/spinlock.h>
#include <linux/dma-mapping.h>
@@ -1727,10 +1728,12 @@ static int adpt_open(struct inode *inode, struct file *file)
int minor;
adpt_hba* pHba;
+ lock_kernel();
//TODO check for root access
//
minor = iminor(inode);
if (minor >= hba_count) {
+ unlock_kernel();
return -ENXIO;
}
mutex_lock(&adpt_configuration_lock);
@@ -1741,6 +1744,7 @@ static int adpt_open(struct inode *inode, struct file *file)
}
if (pHba == NULL) {
mutex_unlock(&adpt_configuration_lock);
+ unlock_kernel();
return -ENXIO;
}
@@ -1751,6 +1755,7 @@ static int adpt_open(struct inode *inode, struct file *file)
pHba->in_use = 1;
mutex_unlock(&adpt_configuration_lock);
+ unlock_kernel();
return 0;
}
diff --git a/drivers/scsi/esp_scsi.c b/drivers/scsi/esp_scsi.c
index a0b6d414953..59fbef08d69 100644
--- a/drivers/scsi/esp_scsi.c
+++ b/drivers/scsi/esp_scsi.c
@@ -2359,6 +2359,24 @@ void scsi_esp_unregister(struct esp *esp)
}
EXPORT_SYMBOL(scsi_esp_unregister);
+static int esp_target_alloc(struct scsi_target *starget)
+{
+ struct esp *esp = shost_priv(dev_to_shost(&starget->dev));
+ struct esp_target_data *tp = &esp->target[starget->id];
+
+ tp->starget = starget;
+
+ return 0;
+}
+
+static void esp_target_destroy(struct scsi_target *starget)
+{
+ struct esp *esp = shost_priv(dev_to_shost(&starget->dev));
+ struct esp_target_data *tp = &esp->target[starget->id];
+
+ tp->starget = NULL;
+}
+
static int esp_slave_alloc(struct scsi_device *dev)
{
struct esp *esp = shost_priv(dev->host);
@@ -2370,8 +2388,6 @@ static int esp_slave_alloc(struct scsi_device *dev)
return -ENOMEM;
dev->hostdata = lp;
- tp->starget = dev->sdev_target;
-
spi_min_period(tp->starget) = esp->min_period;
spi_max_offset(tp->starget) = 15;
@@ -2608,6 +2624,8 @@ struct scsi_host_template scsi_esp_template = {
.name = "esp",
.info = esp_info,
.queuecommand = esp_queuecommand,
+ .target_alloc = esp_target_alloc,
+ .target_destroy = esp_target_destroy,
.slave_alloc = esp_slave_alloc,
.slave_configure = esp_slave_configure,
.slave_destroy = esp_slave_destroy,
diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c
index 46771d4c81b..822d5214692 100644
--- a/drivers/scsi/gdth.c
+++ b/drivers/scsi/gdth.c
@@ -120,6 +120,7 @@
#include <linux/timer.h>
#include <linux/dma-mapping.h>
#include <linux/list.h>
+#include <linux/smp_lock.h>
#ifdef GDTH_RTC
#include <linux/mc146818rtc.h>
@@ -4019,10 +4020,12 @@ static int gdth_open(struct inode *inode, struct file *filep)
{
gdth_ha_str *ha;
+ lock_kernel();
list_for_each_entry(ha, &gdth_instances, list) {
if (!ha->sdev)
ha->sdev = scsi_get_host_dev(ha->shost);
}
+ unlock_kernel();
TRACE(("gdth_open()\n"));
return 0;
diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c
index 3690360d7a7..c6457bfc8a4 100644
--- a/drivers/scsi/hosts.c
+++ b/drivers/scsi/hosts.c
@@ -456,6 +456,10 @@ static int __scsi_host_match(struct device *dev, void *data)
*
* Return value:
* A pointer to located Scsi_Host or NULL.
+ *
+ * The caller must do a scsi_host_put() to drop the reference
+ * that scsi_host_get() took. The put_device() below dropped
+ * the reference from class_find_device().
**/
struct Scsi_Host *scsi_host_lookup(unsigned short hostnum)
{
@@ -463,9 +467,10 @@ struct Scsi_Host *scsi_host_lookup(unsigned short hostnum)
struct Scsi_Host *shost = ERR_PTR(-ENXIO);
cdev = class_find_device(&shost_class, &hostnum, __scsi_host_match);
- if (cdev)
+ if (cdev) {
shost = scsi_host_get(class_to_shost(cdev));
-
+ put_device(cdev);
+ }
return shost;
}
EXPORT_SYMBOL(scsi_host_lookup);
diff --git a/drivers/scsi/hptiop.c b/drivers/scsi/hptiop.c
index aaa48e0c8ed..da876d3924b 100644
--- a/drivers/scsi/hptiop.c
+++ b/drivers/scsi/hptiop.c
@@ -444,7 +444,7 @@ static void __iomem *hptiop_map_pci_bar(struct hptiop_hba *hba, int index)
if (!(pci_resource_flags(pcidev, index) & IORESOURCE_MEM)) {
printk(KERN_ERR "scsi%d: pci resource invalid\n",
hba->host->host_no);
- return 0;
+ return NULL;
}
mem_base_phy = pci_resource_start(pcidev, index);
@@ -454,7 +454,7 @@ static void __iomem *hptiop_map_pci_bar(struct hptiop_hba *hba, int index)
if (!mem_base_virt) {
printk(KERN_ERR "scsi%d: Fail to ioremap memory space\n",
hba->host->host_no);
- return 0;
+ return NULL;
}
return mem_base_virt;
}
@@ -476,11 +476,11 @@ static void hptiop_unmap_pci_bar_itl(struct hptiop_hba *hba)
static int hptiop_map_pci_bar_mv(struct hptiop_hba *hba)
{
hba->u.mv.regs = hptiop_map_pci_bar(hba, 0);
- if (hba->u.mv.regs == 0)
+ if (hba->u.mv.regs == NULL)
return -1;
hba->u.mv.mu = hptiop_map_pci_bar(hba, 2);
- if (hba->u.mv.mu == 0) {
+ if (hba->u.mv.mu == NULL) {
iounmap(hba->u.mv.regs);
return -1;
}
@@ -1210,8 +1210,8 @@ static void hptiop_remove(struct pci_dev *pcidev)
static struct hptiop_adapter_ops hptiop_itl_ops = {
.iop_wait_ready = iop_wait_ready_itl,
- .internal_memalloc = 0,
- .internal_memfree = 0,
+ .internal_memalloc = NULL,
+ .internal_memfree = NULL,
.map_pci_bar = hptiop_map_pci_bar_itl,
.unmap_pci_bar = hptiop_unmap_pci_bar_itl,
.enable_intr = hptiop_enable_intr_itl,
diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c
index ccfd8aca376..5d23368a1bc 100644
--- a/drivers/scsi/ibmvscsi/ibmvscsi.c
+++ b/drivers/scsi/ibmvscsi/ibmvscsi.c
@@ -1348,7 +1348,7 @@ void ibmvscsi_handle_crq(struct viosrp_crq *crq,
del_timer(&evt_struct->timer);
- if (crq->status != VIOSRP_OK && evt_struct->cmnd)
+ if ((crq->status != VIOSRP_OK && crq->status != VIOSRP_OK2) && evt_struct->cmnd)
evt_struct->cmnd->result = DID_ERROR << 16;
if (evt_struct->done)
evt_struct->done(evt_struct);
diff --git a/drivers/scsi/ibmvscsi/viosrp.h b/drivers/scsi/ibmvscsi/viosrp.h
index 4c4aadb3e40..204604501ad 100644
--- a/drivers/scsi/ibmvscsi/viosrp.h
+++ b/drivers/scsi/ibmvscsi/viosrp.h
@@ -65,7 +65,8 @@ enum viosrp_crq_status {
VIOSRP_VIOLATES_MAX_XFER = 0x2,
VIOSRP_PARTNER_PANIC = 0x3,
VIOSRP_DEVICE_BUSY = 0x8,
- VIOSRP_ADAPTER_FAIL = 0x10
+ VIOSRP_ADAPTER_FAIL = 0x10,
+ VIOSRP_OK2 = 0x99,
};
struct viosrp_crq {
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index 999e91ea745..e7a3a655442 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -71,6 +71,7 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/libata.h>
+#include <linux/hdreg.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/processor.h>
@@ -4913,8 +4914,11 @@ static int ipr_ioctl(struct scsi_device *sdev, int cmd, void __user *arg)
struct ipr_resource_entry *res;
res = (struct ipr_resource_entry *)sdev->hostdata;
- if (res && ipr_is_gata(res))
+ if (res && ipr_is_gata(res)) {
+ if (cmd == HDIO_GET_IDENTITY)
+ return -ENOTTY;
return ata_scsi_ioctl(sdev, cmd, arg);
+ }
return -EINVAL;
}
diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c
index 18551aaf5e0..28c9da7d4a5 100644
--- a/drivers/scsi/megaraid.c
+++ b/drivers/scsi/megaraid.c
@@ -46,6 +46,7 @@
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/dma-mapping.h>
+#include <linux/smp_lock.h>
#include <scsi/scsicam.h>
#include "scsi.h"
@@ -3272,12 +3273,12 @@ mega_init_scb(adapter_t *adapter)
* @filep - unused
*
* Routines for the character/ioctl interface to the driver. Find out if this
- * is a valid open. If yes, increment the module use count so that it cannot
- * be unloaded.
+ * is a valid open.
*/
static int
megadev_open (struct inode *inode, struct file *filep)
{
+ cycle_kernel_lock();
/*
* Only allow superuser to access private ioctl interface
*/
diff --git a/drivers/scsi/megaraid/megaraid_mm.c b/drivers/scsi/megaraid/megaraid_mm.c
index 0ad215e27b8..ac3b280c2a7 100644
--- a/drivers/scsi/megaraid/megaraid_mm.c
+++ b/drivers/scsi/megaraid/megaraid_mm.c
@@ -15,6 +15,7 @@
* Common management module
*/
#include <linux/sched.h>
+#include <linux/smp_lock.h>
#include "megaraid_mm.h"
@@ -96,6 +97,7 @@ mraid_mm_open(struct inode *inode, struct file *filep)
*/
if (!capable(CAP_SYS_ADMIN)) return (-EACCES);
+ cycle_kernel_lock();
return 0;
}
diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c
index 7d84c8bbcf3..fc7ac158476 100644
--- a/drivers/scsi/megaraid/megaraid_sas.c
+++ b/drivers/scsi/megaraid/megaraid_sas.c
@@ -33,6 +33,7 @@
#include <linux/spinlock.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
+#include <linux/smp_lock.h>
#include <linux/uio.h>
#include <asm/uaccess.h>
#include <linux/fs.h>
@@ -2863,6 +2864,7 @@ static void megasas_shutdown(struct pci_dev *pdev)
*/
static int megasas_mgmt_open(struct inode *inode, struct file *filep)
{
+ cycle_kernel_lock();
/*
* Allow only those users with admin rights
*/
diff --git a/drivers/scsi/osst.c b/drivers/scsi/osst.c
index 243d8becd30..1c79f9794f4 100644
--- a/drivers/scsi/osst.c
+++ b/drivers/scsi/osst.c
@@ -50,6 +50,7 @@ static const char * osst_version = "0.99.4";
#include <linux/moduleparam.h>
#include <linux/delay.h>
#include <linux/jiffies.h>
+#include <linux/smp_lock.h>
#include <asm/uaccess.h>
#include <asm/dma.h>
#include <asm/system.h>
@@ -4359,7 +4360,7 @@ os_bypass:
/* Open the device */
-static int os_scsi_tape_open(struct inode * inode, struct file * filp)
+static int __os_scsi_tape_open(struct inode * inode, struct file * filp)
{
unsigned short flags;
int i, b_size, new_session = 0, retval = 0;
@@ -4725,6 +4726,18 @@ err_out:
return retval;
}
+/* BKL pushdown: spaghetti avoidance wrapper */
+static int os_scsi_tape_open(struct inode * inode, struct file * filp)
+{
+ int ret;
+
+ lock_kernel();
+ ret = __os_scsi_tape_open(inode, filp);
+ unlock_kernel();
+ return ret;
+}
+
+
/* Flush the tape buffer before close */
static int os_scsi_tape_flush(struct file * filp, fl_owner_t id)
diff --git a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c
index 51e2f299dbb..3754ab87f89 100644
--- a/drivers/scsi/qla1280.c
+++ b/drivers/scsi/qla1280.c
@@ -2811,7 +2811,7 @@ qla1280_64bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
/* Check for room in outstanding command list. */
for (cnt = 0; cnt < MAX_OUTSTANDING_COMMANDS &&
- ha->outstanding_cmds[cnt] != 0; cnt++);
+ ha->outstanding_cmds[cnt] != NULL; cnt++);
if (cnt >= MAX_OUTSTANDING_COMMANDS) {
status = 1;
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
index 287690853ca..8dd88fc1244 100644
--- a/drivers/scsi/qla2xxx/qla_attr.c
+++ b/drivers/scsi/qla2xxx/qla_attr.c
@@ -70,6 +70,9 @@ qla2x00_sysfs_write_fw_dump(struct kobject *kobj,
case 2:
qla2x00_alloc_fw_dump(ha);
break;
+ case 3:
+ qla2x00_system_error(ha);
+ break;
}
return (count);
}
@@ -886,9 +889,13 @@ qla2x00_get_host_speed(struct Scsi_Host *shost)
static void
qla2x00_get_host_port_type(struct Scsi_Host *shost)
{
- scsi_qla_host_t *ha = to_qla_parent(shost_priv(shost));
+ scsi_qla_host_t *ha = shost_priv(shost);
uint32_t port_type = FC_PORTTYPE_UNKNOWN;
+ if (ha->parent) {
+ fc_host_port_type(shost) = FC_PORTTYPE_NPIV;
+ return;
+ }
switch (ha->current_topology) {
case ISP_CFG_NL:
port_type = FC_PORTTYPE_LPORT;
@@ -1172,10 +1179,10 @@ qla24xx_vport_delete(struct fc_vport *fc_vport)
qla24xx_disable_vp(vha);
qla24xx_deallocate_vp_id(vha);
- down(&ha->vport_sem);
+ mutex_lock(&ha->vport_lock);
ha->cur_vport_count--;
clear_bit(vha->vp_idx, ha->vp_idx_map);
- up(&ha->vport_sem);
+ mutex_unlock(&ha->vport_lock);
kfree(vha->node_name);
kfree(vha->port_name);
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index 299eccf6cab..8dd600013bd 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -2457,7 +2457,7 @@ typedef struct scsi_qla_host {
#define MBX_INTR_WAIT 2
#define MBX_UPDATE_FLASH_ACTIVE 3
- struct semaphore vport_sem; /* Virtual port synchronization */
+ struct mutex vport_lock; /* Virtual port synchronization */
struct completion mbx_cmd_comp; /* Serialize mbx access */
struct completion mbx_intr_comp; /* Used for completion notification */
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index f8827068d30..9b4bebee687 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -228,6 +228,9 @@ extern int qla24xx_abort_target(struct fc_port *, unsigned int);
extern int qla24xx_lun_reset(struct fc_port *, unsigned int);
extern int
+qla2x00_system_error(scsi_qla_host_t *);
+
+extern int
qla2x00_set_serdes_params(scsi_qla_host_t *, uint16_t, uint16_t, uint16_t);
extern int
diff --git a/drivers/scsi/qla2xxx/qla_inline.h b/drivers/scsi/qla2xxx/qla_inline.h
index e9bae27737d..92fafbdbbaa 100644
--- a/drivers/scsi/qla2xxx/qla_inline.h
+++ b/drivers/scsi/qla2xxx/qla_inline.h
@@ -34,7 +34,11 @@ qla2x00_debounce_register(volatile uint16_t __iomem *addr)
static inline void
qla2x00_poll(scsi_qla_host_t *ha)
{
+ unsigned long flags;
+
+ local_irq_save(flags);
ha->isp_ops->intr_handler(0, ha);
+ local_irq_restore(flags);
}
static __inline__ scsi_qla_host_t *
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index 5d9a64a7879..ec63b79f900 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -272,8 +272,6 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
uint32_t rscn_entry, host_pid;
uint8_t rscn_queue_index;
unsigned long flags;
- scsi_qla_host_t *vha;
- int i;
/* Setup to process RIO completion. */
handle_cnt = 0;
@@ -544,18 +542,10 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
break;
case MBA_PORT_UPDATE: /* Port database update */
- if ((ha->flags.npiv_supported) && (ha->num_vhosts)) {
- for_each_mapped_vp_idx(ha, i) {
- list_for_each_entry(vha, &ha->vp_list,
- vp_list) {
- if ((mb[3] & 0xff)
- == vha->vp_idx) {
- ha = vha;
- break;
- }
- }
- }
- }
+ /* Only handle SCNs for our Vport index. */
+ if (ha->parent && ha->vp_idx != (mb[3] & 0xff))
+ break;
+
/*
* If PORT UPDATE is global (recieved LIP_OCCURED/LIP_RESET
* event etc. earlier indicating loop is down) then process
@@ -590,18 +580,12 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
break;
case MBA_RSCN_UPDATE: /* State Change Registration */
- if ((ha->flags.npiv_supported) && (ha->num_vhosts)) {
- for_each_mapped_vp_idx(ha, i) {
- list_for_each_entry(vha, &ha->vp_list,
- vp_list) {
- if ((mb[3] & 0xff)
- == vha->vp_idx) {
- ha = vha;
- break;
- }
- }
- }
- }
+ /* Check if the Vport has issued a SCR */
+ if (ha->parent && test_bit(VP_SCR_NEEDED, &ha->vp_flags))
+ break;
+ /* Only handle SCNs for our Vport index. */
+ if (ha->parent && ha->vp_idx != (mb[3] & 0xff))
+ break;
DEBUG2(printk("scsi(%ld): Asynchronous RSCR UPDATE.\n",
ha->host_no));
@@ -1132,25 +1116,6 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt)
break;
qla2x00_handle_sense(sp, sense_data, sense_len);
-
- /*
- * In case of a Underrun condition, set both the lscsi
- * status and the completion status to appropriate
- * values.
- */
- if (resid &&
- ((unsigned)(scsi_bufflen(cp) - resid) <
- cp->underflow)) {
- DEBUG2(qla_printk(KERN_INFO, ha,
- "scsi(%ld:%d:%d:%d): Mid-layer underflow "
- "detected (%x of %x bytes)...returning "
- "error status.\n", ha->host_no,
- cp->device->channel, cp->device->id,
- cp->device->lun, resid,
- scsi_bufflen(cp)));
-
- cp->result = DID_ERROR << 16 | lscsi_status;
- }
} else {
/*
* If RISC reports underrun and target does not report
@@ -1639,12 +1604,12 @@ qla24xx_msix_rsp_q(int irq, void *dev_id)
ha = dev_id;
reg = &ha->iobase->isp24;
- spin_lock(&ha->hardware_lock);
+ spin_lock_irq(&ha->hardware_lock);
qla24xx_process_response_queue(ha);
WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_INT);
- spin_unlock(&ha->hardware_lock);
+ spin_unlock_irq(&ha->hardware_lock);
return IRQ_HANDLED;
}
@@ -1663,7 +1628,7 @@ qla24xx_msix_default(int irq, void *dev_id)
reg = &ha->iobase->isp24;
status = 0;
- spin_lock(&ha->hardware_lock);
+ spin_lock_irq(&ha->hardware_lock);
do {
stat = RD_REG_DWORD(&reg->host_status);
if (stat & HSRX_RISC_PAUSED) {
@@ -1716,7 +1681,7 @@ qla24xx_msix_default(int irq, void *dev_id)
}
WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_INT);
} while (0);
- spin_unlock(&ha->hardware_lock);
+ spin_unlock_irq(&ha->hardware_lock);
if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) &&
(status & MBX_INTERRUPT) && ha->flags.mbox_int) {
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
index 21006042080..250d2f60439 100644
--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
@@ -2303,8 +2303,6 @@ qla24xx_lun_reset(struct fc_port *fcport, unsigned int l)
return __qla24xx_issue_tmf("Lun", TCF_LUN_RESET, fcport, l);
}
-#if 0
-
int
qla2x00_system_error(scsi_qla_host_t *ha)
{
@@ -2312,7 +2310,7 @@ qla2x00_system_error(scsi_qla_host_t *ha)
mbx_cmd_t mc;
mbx_cmd_t *mcp = &mc;
- if (!IS_FWI2_CAPABLE(ha))
+ if (!IS_QLA23XX(ha) && !IS_FWI2_CAPABLE(ha))
return QLA_FUNCTION_FAILED;
DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no));
@@ -2334,8 +2332,6 @@ qla2x00_system_error(scsi_qla_host_t *ha)
return rval;
}
-#endif /* 0 */
-
/**
* qla2x00_set_serdes_params() -
* @ha: HA context
@@ -2508,7 +2504,7 @@ qla2x00_enable_fce_trace(scsi_qla_host_t *ha, dma_addr_t fce_dma,
if (mb)
memcpy(mb, mcp->mb, 8 * sizeof(*mb));
if (dwords)
- *dwords = mcp->mb[6];
+ *dwords = buffers;
}
return rval;
@@ -2807,9 +2803,9 @@ qla24xx_control_vp(scsi_qla_host_t *vha, int cmd)
*/
map = (vp_index - 1) / 8;
pos = (vp_index - 1) & 7;
- down(&ha->vport_sem);
+ mutex_lock(&ha->vport_lock);
vce->vp_idx_map[map] |= 1 << pos;
- up(&ha->vport_sem);
+ mutex_unlock(&ha->vport_lock);
rval = qla2x00_issue_iocb(ha, vce, vce_dma, 0);
if (rval != QLA_SUCCESS) {
diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c
index f2b04979e5f..62a3ad6e8ec 100644
--- a/drivers/scsi/qla2xxx/qla_mid.c
+++ b/drivers/scsi/qla2xxx/qla_mid.c
@@ -32,12 +32,12 @@ qla24xx_allocate_vp_id(scsi_qla_host_t *vha)
scsi_qla_host_t *ha = vha->parent;
/* Find an empty slot and assign an vp_id */
- down(&ha->vport_sem);
+ mutex_lock(&ha->vport_lock);
vp_id = find_first_zero_bit(ha->vp_idx_map, ha->max_npiv_vports + 1);
if (vp_id > ha->max_npiv_vports) {
DEBUG15(printk ("vp_id %d is bigger than max-supported %d.\n",
vp_id, ha->max_npiv_vports));
- up(&ha->vport_sem);
+ mutex_unlock(&ha->vport_lock);
return vp_id;
}
@@ -45,7 +45,7 @@ qla24xx_allocate_vp_id(scsi_qla_host_t *vha)
ha->num_vhosts++;
vha->vp_idx = vp_id;
list_add_tail(&vha->vp_list, &ha->vp_list);
- up(&ha->vport_sem);
+ mutex_unlock(&ha->vport_lock);
return vp_id;
}
@@ -55,12 +55,12 @@ qla24xx_deallocate_vp_id(scsi_qla_host_t *vha)
uint16_t vp_id;
scsi_qla_host_t *ha = vha->parent;
- down(&ha->vport_sem);
+ mutex_lock(&ha->vport_lock);
vp_id = vha->vp_idx;
ha->num_vhosts--;
clear_bit(vp_id, ha->vp_idx_map);
list_del(&vha->vp_list);
- up(&ha->vport_sem);
+ mutex_unlock(&ha->vport_lock);
}
static scsi_qla_host_t *
@@ -145,9 +145,9 @@ qla24xx_enable_vp(scsi_qla_host_t *vha)
}
/* Initialize the new vport unless it is a persistent port */
- down(&ha->vport_sem);
+ mutex_lock(&ha->vport_lock);
ret = qla24xx_modify_vp_config(vha);
- up(&ha->vport_sem);
+ mutex_unlock(&ha->vport_lock);
if (ret != QLA_SUCCESS) {
fc_vport_set_state(vha->fc_vport, FC_VPORT_FAILED);
@@ -406,6 +406,7 @@ qla24xx_create_vhost(struct fc_vport *fc_vport)
INIT_LIST_HEAD(&vha->list);
INIT_LIST_HEAD(&vha->fcports);
INIT_LIST_HEAD(&vha->vp_fcports);
+ INIT_LIST_HEAD(&vha->work_list);
vha->dpc_flags = 0L;
set_bit(REGISTER_FDMI_NEEDED, &vha->dpc_flags);
@@ -437,10 +438,10 @@ qla24xx_create_vhost(struct fc_vport *fc_vport)
vha->flags.init_done = 1;
num_hosts++;
- down(&ha->vport_sem);
+ mutex_lock(&ha->vport_lock);
set_bit(vha->vp_idx, ha->vp_idx_map);
ha->cur_vport_count++;
- up(&ha->vport_sem);
+ mutex_unlock(&ha->vport_lock);
return vha;
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 3223fd16bcf..48eaa3bb543 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -10,6 +10,7 @@
#include <linux/vmalloc.h>
#include <linux/delay.h>
#include <linux/kthread.h>
+#include <linux/mutex.h>
#include <scsi/scsi_tcq.h>
#include <scsi/scsicam.h>
@@ -1631,7 +1632,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
/* load the F/W, read paramaters, and init the H/W */
ha->instance = num_hosts;
- init_MUTEX(&ha->vport_sem);
+ mutex_init(&ha->vport_lock);
init_completion(&ha->mbx_cmd_comp);
complete(&ha->mbx_cmd_comp);
init_completion(&ha->mbx_intr_comp);
@@ -2156,13 +2157,14 @@ static int
qla2x00_post_work(struct scsi_qla_host *ha, struct qla_work_evt *e, int locked)
{
unsigned long flags;
+ scsi_qla_host_t *pha = to_qla_parent(ha);
if (!locked)
- spin_lock_irqsave(&ha->hardware_lock, flags);
+ spin_lock_irqsave(&pha->hardware_lock, flags);
list_add_tail(&e->list, &ha->work_list);
qla2xxx_wake_dpc(ha);
if (!locked)
- spin_unlock_irqrestore(&ha->hardware_lock, flags);
+ spin_unlock_irqrestore(&pha->hardware_lock, flags);
return QLA_SUCCESS;
}
@@ -2202,12 +2204,13 @@ static void
qla2x00_do_work(struct scsi_qla_host *ha)
{
struct qla_work_evt *e;
+ scsi_qla_host_t *pha = to_qla_parent(ha);
- spin_lock_irq(&ha->hardware_lock);
+ spin_lock_irq(&pha->hardware_lock);
while (!list_empty(&ha->work_list)) {
e = list_entry(ha->work_list.next, struct qla_work_evt, list);
list_del_init(&e->list);
- spin_unlock_irq(&ha->hardware_lock);
+ spin_unlock_irq(&pha->hardware_lock);
switch (e->type) {
case QLA_EVT_AEN:
@@ -2221,9 +2224,9 @@ qla2x00_do_work(struct scsi_qla_host *ha)
}
if (e->flags & QLA_EVT_FLAG_FREE)
kfree(e);
- spin_lock_irq(&ha->hardware_lock);
+ spin_lock_irq(&pha->hardware_lock);
}
- spin_unlock_irq(&ha->hardware_lock);
+ spin_unlock_irq(&pha->hardware_lock);
}
/**************************************************************************
@@ -2634,7 +2637,7 @@ qla2x00_timer(scsi_qla_host_t *ha)
#define FW_FILE_ISP24XX "ql2400_fw.bin"
#define FW_FILE_ISP25XX "ql2500_fw.bin"
-static DECLARE_MUTEX(qla_fw_lock);
+static DEFINE_MUTEX(qla_fw_lock);
static struct fw_blob qla_fw_blobs[FW_BLOBS] = {
{ .name = FW_FILE_ISP21XX, .segs = { 0x1000, 0 }, },
@@ -2665,7 +2668,7 @@ qla2x00_request_firmware(scsi_qla_host_t *ha)
blob = &qla_fw_blobs[FW_ISP25XX];
}
- down(&qla_fw_lock);
+ mutex_lock(&qla_fw_lock);
if (blob->fw)
goto out;
@@ -2678,7 +2681,7 @@ qla2x00_request_firmware(scsi_qla_host_t *ha)
}
out:
- up(&qla_fw_lock);
+ mutex_unlock(&qla_fw_lock);
return blob;
}
@@ -2687,11 +2690,11 @@ qla2x00_release_firmware(void)
{
int idx;
- down(&qla_fw_lock);
+ mutex_lock(&qla_fw_lock);
for (idx = 0; idx < FW_BLOBS; idx++)
if (qla_fw_blobs[idx].fw)
release_firmware(qla_fw_blobs[idx].fw);
- up(&qla_fw_lock);
+ mutex_unlock(&qla_fw_lock);
}
static pci_ers_result_t
@@ -2864,7 +2867,8 @@ qla2x00_module_init(void)
return -ENODEV;
}
- printk(KERN_INFO "QLogic Fibre Channel HBA Driver\n");
+ printk(KERN_INFO "QLogic Fibre Channel HBA Driver: %s\n",
+ qla2x00_version_str);
ret = pci_register_driver(&qla2xxx_pci_driver);
if (ret) {
kmem_cache_destroy(srb_cachep);
diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h
index afeae2bfe7e..d058c8862b3 100644
--- a/drivers/scsi/qla2xxx/qla_version.h
+++ b/drivers/scsi/qla2xxx/qla_version.h
@@ -7,7 +7,7 @@
/*
* Driver version
*/
-#define QLA2XXX_VERSION "8.02.01-k2"
+#define QLA2XXX_VERSION "8.02.01-k4"
#define QLA_DRIVER_MAJOR_VER 8
#define QLA_DRIVER_MINOR_VER 2
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index a82d2fe80fb..cbf55d59a54 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -207,6 +207,15 @@ int scsi_execute(struct scsi_device *sdev, const unsigned char *cmd,
*/
blk_execute_rq(req->q, NULL, req, 1);
+ /*
+ * Some devices (USB mass-storage in particular) may transfer
+ * garbage data together with a residue indicating that the data
+ * is invalid. Prevent the garbage from being misinterpreted
+ * and prevent security leaks by zeroing out the excess data.
+ */
+ if (unlikely(req->data_len > 0 && req->data_len <= bufflen))
+ memset(buffer + (bufflen - req->data_len), 0, req->data_len);
+
ret = req->errors;
out:
blk_put_request(req);
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
index 049103f1d16..93d2b671445 100644
--- a/drivers/scsi/scsi_sysfs.c
+++ b/drivers/scsi/scsi_sysfs.c
@@ -359,7 +359,12 @@ static int scsi_bus_match(struct device *dev, struct device_driver *gendrv)
static int scsi_bus_uevent(struct device *dev, struct kobj_uevent_env *env)
{
- struct scsi_device *sdev = to_scsi_device(dev);
+ struct scsi_device *sdev;
+
+ if (dev->type != &scsi_dev_type)
+ return 0;
+
+ sdev = to_scsi_device(dev);
add_uevent_var(env, "MODALIAS=" SCSI_DEVICE_MODALIAS_FMT, sdev->type);
return 0;
diff --git a/drivers/scsi/scsi_tgt_if.c b/drivers/scsi/scsi_tgt_if.c
index d2557dbc2dc..0e9533f7aab 100644
--- a/drivers/scsi/scsi_tgt_if.c
+++ b/drivers/scsi/scsi_tgt_if.c
@@ -21,6 +21,7 @@
*/
#include <linux/miscdevice.h>
#include <linux/file.h>
+#include <linux/smp_lock.h>
#include <net/tcp.h>
#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
@@ -321,6 +322,7 @@ static int tgt_open(struct inode *inode, struct file *file)
{
tx_ring.tr_idx = rx_ring.tr_idx = 0;
+ cycle_kernel_lock();
return 0;
}
diff --git a/drivers/scsi/ses.c b/drivers/scsi/ses.c
index 45df83b9d84..0fe031f003e 100644
--- a/drivers/scsi/ses.c
+++ b/drivers/scsi/ses.c
@@ -61,7 +61,7 @@ static int ses_probe(struct device *dev)
return err;
}
-#define SES_TIMEOUT 30
+#define SES_TIMEOUT (30 * HZ)
#define SES_RETRIES 3
static int ses_recv_diag(struct scsi_device *sdev, int page_code,
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index ea0edd1b2e7..fccd2e88d60 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -49,6 +49,7 @@ static int sg_version_num = 30534; /* 2 digits for each component */
#include <linux/delay.h>
#include <linux/scatterlist.h>
#include <linux/blktrace_api.h>
+#include <linux/smp_lock.h>
#include "scsi.h"
#include <scsi/scsi_dbg.h>
@@ -182,8 +183,9 @@ static int sg_build_sgat(Sg_scatter_hold * schp, const Sg_fd * sfp,
int tablesize);
static ssize_t sg_new_read(Sg_fd * sfp, char __user *buf, size_t count,
Sg_request * srp);
-static ssize_t sg_new_write(Sg_fd * sfp, const char __user *buf, size_t count,
- int blocking, int read_only, Sg_request ** o_srp);
+static ssize_t sg_new_write(Sg_fd *sfp, struct file *file,
+ const char __user *buf, size_t count, int blocking,
+ int read_only, Sg_request **o_srp);
static int sg_common_write(Sg_fd * sfp, Sg_request * srp,
unsigned char *cmnd, int timeout, int blocking);
static int sg_u_iovec(sg_io_hdr_t * hp, int sg_num, int ind,
@@ -204,7 +206,6 @@ static Sg_request *sg_get_rq_mark(Sg_fd * sfp, int pack_id);
static Sg_request *sg_add_request(Sg_fd * sfp);
static int sg_remove_request(Sg_fd * sfp, Sg_request * srp);
static int sg_res_in_use(Sg_fd * sfp);
-static int sg_allow_access(unsigned char opcode, char dev_type);
static int sg_build_direct(Sg_request * srp, Sg_fd * sfp, int dxfer_len);
static Sg_device *sg_get_dev(int dev);
#ifdef CONFIG_SCSI_PROC_FS
@@ -227,19 +228,26 @@ sg_open(struct inode *inode, struct file *filp)
int res;
int retval;
+ lock_kernel();
nonseekable_open(inode, filp);
SCSI_LOG_TIMEOUT(3, printk("sg_open: dev=%d, flags=0x%x\n", dev, flags));
sdp = sg_get_dev(dev);
- if ((!sdp) || (!sdp->device))
+ if ((!sdp) || (!sdp->device)) {
+ unlock_kernel();
return -ENXIO;
- if (sdp->detached)
+ }
+ if (sdp->detached) {
+ unlock_kernel();
return -ENODEV;
+ }
/* This driver's module count bumped by fops_get in <linux/fs.h> */
/* Prevent the device driver from vanishing while we sleep */
retval = scsi_device_get(sdp->device);
- if (retval)
+ if (retval) {
+ unlock_kernel();
return retval;
+ }
if (!((flags & O_NONBLOCK) ||
scsi_block_when_processing_errors(sdp->device))) {
@@ -295,10 +303,12 @@ sg_open(struct inode *inode, struct file *filp)
retval = -ENOMEM;
goto error_out;
}
+ unlock_kernel();
return 0;
error_out:
scsi_device_put(sdp->device);
+ unlock_kernel();
return retval;
}
@@ -544,7 +554,7 @@ sg_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos)
return -EFAULT;
blocking = !(filp->f_flags & O_NONBLOCK);
if (old_hdr.reply_len < 0)
- return sg_new_write(sfp, buf, count, blocking, 0, NULL);
+ return sg_new_write(sfp, filp, buf, count, blocking, 0, NULL);
if (count < (SZ_SG_HEADER + 6))
return -EIO; /* The minimum scsi command length is 6 bytes. */
@@ -621,8 +631,9 @@ sg_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos)
}
static ssize_t
-sg_new_write(Sg_fd * sfp, const char __user *buf, size_t count,
- int blocking, int read_only, Sg_request ** o_srp)
+sg_new_write(Sg_fd *sfp, struct file *file, const char __user *buf,
+ size_t count, int blocking, int read_only,
+ Sg_request **o_srp)
{
int k;
Sg_request *srp;
@@ -678,8 +689,7 @@ sg_new_write(Sg_fd * sfp, const char __user *buf, size_t count,
sg_remove_request(sfp, srp);
return -EFAULT;
}
- if (read_only &&
- (!sg_allow_access(cmnd[0], sfp->parentdp->device->type))) {
+ if (read_only && !blk_verify_command(file, cmnd)) {
sg_remove_request(sfp, srp);
return -EPERM;
}
@@ -799,7 +809,7 @@ sg_ioctl(struct inode *inode, struct file *filp,
if (!access_ok(VERIFY_WRITE, p, SZ_SG_IO_HDR))
return -EFAULT;
result =
- sg_new_write(sfp, p, SZ_SG_IO_HDR,
+ sg_new_write(sfp, filp, p, SZ_SG_IO_HDR,
blocking, read_only, &srp);
if (result < 0)
return result;
@@ -1048,7 +1058,7 @@ sg_ioctl(struct inode *inode, struct file *filp,
if (copy_from_user(&opcode, siocp->data, 1))
return -EFAULT;
- if (!sg_allow_access(opcode, sdp->device->type))
+ if (!blk_verify_command(filp, &opcode))
return -EPERM;
}
return sg_scsi_ioctl(filp, sdp->device->request_queue, NULL, p);
@@ -2502,30 +2512,6 @@ sg_page_free(struct page *page, int size)
__free_pages(page, order);
}
-#ifndef MAINTENANCE_IN_CMD
-#define MAINTENANCE_IN_CMD 0xa3
-#endif
-
-static unsigned char allow_ops[] = { TEST_UNIT_READY, REQUEST_SENSE,
- INQUIRY, READ_CAPACITY, READ_BUFFER, READ_6, READ_10, READ_12,
- READ_16, MODE_SENSE, MODE_SENSE_10, LOG_SENSE, REPORT_LUNS,
- SERVICE_ACTION_IN, RECEIVE_DIAGNOSTIC, READ_LONG, MAINTENANCE_IN_CMD
-};
-
-static int
-sg_allow_access(unsigned char opcode, char dev_type)
-{
- int k;
-
- if (TYPE_SCANNER == dev_type) /* TYPE_ROM maybe burner */
- return 1;
- for (k = 0; k < sizeof (allow_ops); ++k) {
- if (opcode == allow_ops[k])
- return 1;
- }
- return 0;
-}
-
#ifdef CONFIG_SCSI_PROC_FS
static int
sg_idr_max_id(int id, void *p, void *data)
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c
index 7ee86d4a761..27f5bfd1def 100644
--- a/drivers/scsi/sr.c
+++ b/drivers/scsi/sr.c
@@ -178,6 +178,9 @@ int sr_test_unit_ready(struct scsi_device *sdev, struct scsi_sense_hdr *sshdr)
the_result = scsi_execute_req(sdev, cmd, DMA_NONE, NULL,
0, sshdr, SR_TIMEOUT,
retries--);
+ if (scsi_sense_valid(sshdr) &&
+ sshdr->sense_key == UNIT_ATTENTION)
+ sdev->changed = 1;
} while (retries > 0 &&
(!scsi_status_is_good(the_result) ||
@@ -670,24 +673,20 @@ fail:
static void get_sectorsize(struct scsi_cd *cd)
{
unsigned char cmd[10];
- unsigned char *buffer;
+ unsigned char buffer[8];
int the_result, retries = 3;
int sector_size;
struct request_queue *queue;
- buffer = kmalloc(512, GFP_KERNEL | GFP_DMA);
- if (!buffer)
- goto Enomem;
-
do {
cmd[0] = READ_CAPACITY;
memset((void *) &cmd[1], 0, 9);
- memset(buffer, 0, 8);
+ memset(buffer, 0, sizeof(buffer));
/* Do the command and wait.. */
the_result = scsi_execute_req(cd->device, cmd, DMA_FROM_DEVICE,
- buffer, 8, NULL, SR_TIMEOUT,
- MAX_RETRIES);
+ buffer, sizeof(buffer), NULL,
+ SR_TIMEOUT, MAX_RETRIES);
retries--;
@@ -742,14 +741,8 @@ static void get_sectorsize(struct scsi_cd *cd)
queue = cd->device->request_queue;
blk_queue_hardsect_size(queue, sector_size);
-out:
- kfree(buffer);
- return;
-Enomem:
- cd->capacity = 0x1fffff;
- cd->device->sector_size = 2048; /* A guess, just in case */
- goto out;
+ return;
}
static void get_capabilities(struct scsi_cd *cd)
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
index 6e5a5bb3131..4684cc716aa 100644
--- a/drivers/scsi/st.c
+++ b/drivers/scsi/st.c
@@ -38,6 +38,7 @@ static const char *verstr = "20080224";
#include <linux/cdev.h>
#include <linux/delay.h>
#include <linux/mutex.h>
+#include <linux/smp_lock.h>
#include <asm/uaccess.h>
#include <asm/dma.h>
@@ -1113,7 +1114,7 @@ static int check_tape(struct scsi_tape *STp, struct file *filp)
}
- /* Open the device. Needs to be called with BKL only because of incrementing the SCSI host
+ /* Open the device. Needs to take the BKL only because of incrementing the SCSI host
module count. */
static int st_open(struct inode *inode, struct file *filp)
{
@@ -1123,6 +1124,7 @@ static int st_open(struct inode *inode, struct file *filp)
int dev = TAPE_NR(inode);
char *name;
+ lock_kernel();
/*
* We really want to do nonseekable_open(inode, filp); here, but some
* versions of tar incorrectly call lseek on tapes and bail out if that
@@ -1130,8 +1132,10 @@ static int st_open(struct inode *inode, struct file *filp)
*/
filp->f_mode &= ~(FMODE_PREAD | FMODE_PWRITE);
- if (!(STp = scsi_tape_get(dev)))
+ if (!(STp = scsi_tape_get(dev))) {
+ unlock_kernel();
return -ENXIO;
+ }
write_lock(&st_dev_arr_lock);
filp->private_data = STp;
@@ -1140,6 +1144,7 @@ static int st_open(struct inode *inode, struct file *filp)
if (STp->in_use) {
write_unlock(&st_dev_arr_lock);
scsi_tape_put(STp);
+ unlock_kernel();
DEB( printk(ST_DEB_MSG "%s: Device already in use.\n", name); )
return (-EBUSY);
}
@@ -1188,12 +1193,14 @@ static int st_open(struct inode *inode, struct file *filp)
retval = (-EIO);
goto err_out;
}
+ unlock_kernel();
return 0;
err_out:
normalize_buffer(STp->buffer);
STp->in_use = 0;
scsi_tape_put(STp);
+ unlock_kernel();
return retval;
}